डेकोरेटर पैटर्न
मैं वास्तव में अच्छी तरह से प्रलेखित Decorator पद्धति का उपयोग कर ArrayList
लपेटकर की सिफारिश करेंगे। आप बस लपेट अपने एक और List
कार्यान्वयन कि तरीकों में से प्रतिनिधियों सबसे लेकिन मान्यता तर्क कहते हैं के साथ ArrayList
:
public class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
@Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
@Override
public boolean add(MyBusinessObject o)
{
validate(o);
return target.add(o);
}
//few more to implement
}
लाभ:
- तुम अब भी सत्यापन के बिना कच्चे सूची तक पहुँच सकते हैं अगर आप चाहते हैं (लेकिन आप कर सकते हैं इसे प्रतिबंधित करें)
- अलग-अलग सत्यापनों को ढेर करना आसान है, उन्हें चुनिंदा रूप से चालू और बंद करें। के रूप में @helios
- द्वारा नोट
- को बढ़ावा देता है composition over inheritance testability
- एक विशिष्ट
List
कार्यान्वयन के लिए आप टाई नहीं करता है में सुधार करता है, तो आप LinkedList
को मान्यता जोड़ सकते हैं या Hibernate लगातार सूचियों समर्थित। आप किसी भी संग्रह को सत्यापित करने के लिए जेनेरिक Collection
सजावट के बारे में भी सोच सकते हैं।
कार्यान्वयन याद नोटों
कार्यान्वयन के बावजूद आप के बारे में याद करने के लिए है तरीकों की काफी एक बहुत देखते हैं, जबकि अधिभावी: (?) add()
, addAll()
, set()
, subList()
, आदि
इसके अलावा अपने ऑब्जेक्ट अपरिवर्तनीय होना चाहिए, अन्यथा उपयोगकर्ता मान्य ऑब्जेक्ट को जोड़/सेट कर सकता है और अनुबंध का उल्लंघन करने के बाद इसे संशोधित कर सकता है।
अच्छा OO डिजाइन
अंत में मैं ने लिखा है:
validate(element)
लेकिन विचार करें:
element.validate()
जो एक बेहतर डिजाइन है।
स्टैकिंग सत्यापन
के रूप में उल्लेख किया पहले अगर आप सत्यापन ढेर, एक भी, अलग कक्षा में प्रत्येक proprty/apsect मान्य चाहते हैं, निम्नलिखित मुहावरा पर विचार करें:
public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
@Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
protected abstract void validate(MyBusinessObject element);
}
... और कुछ कार्यान्वयन :
class FooValidatingDecorator extends ValidatingListDecorator {
public FooValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
@Override
protected void validate(MyBusinessObject element)
{
//throw if "foo" not met
}
}
class BarValidatingDecorator extends ValidatingListDecorator {
public BarValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
@Override
protected void validate(MyBusinessObject element)
{
//throw if "bar" not met
}
}
केवल foo मान्य करने के लिए करना चाहते हैं?
List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);
दोनों foo और बार मान्य करने के लिए करना चाहते हैं?
List<MyBusinessObject> list =
new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));
+1! – helios
+1 बहुत विस्तृत उत्तर के लिए धन्यवाद – Sudhakar