2012-02-20 12 views
7

मैं किसी सरणी सूची में ऑब्जेक्ट्स का संग्रह जोड़ना चाहता हूं, केवल तभी जब विशेष विशेषता शून्य न हो।क्या मुझे ऐसे गुण जोड़ने के लिए ArrayList का विस्तार करना चाहिए जो शून्य नहीं है?

मैं ऐरेलिस्ट को विस्तारित करने और बाल वर्ग के अंदर चेक लागू करने की सोच रहा हूं।

एक वैकल्पिक तरीका एक ArrayList में यह डालने से पहले विशेषता के लिए जाँच करने के लिए है, लेकिन इसका मतलब यह होता है, मैं तितर बितर करना होगा जांच करता है कि हर जगह अगर मैं तर्क के आधार पर ArrayList वस्तुओं जोड़ने की जरूरत ।

मैं इस पर आपके विचार जानना चाहता हूं ... एक दूसरे विचार पर यह एक ओवरकिल है?

उत्तर

20

डेकोरेटर पैटर्न

मैं वास्तव में अच्छी तरह से प्रलेखित 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)); 
+6

+1! – helios

+0

+1 बहुत विस्तृत उत्तर के लिए धन्यवाद – Sudhakar

1

यदि आप इसे लागू करना चाहते हैं तो मुझे नहीं लगता कि क्यों नहीं (हालांकि जब भी आप यह सुनिश्चित करने के लिए जोड़ते हैं कि ऐड विधि का रिटर्न वैल्यू देखना चाहिए)।

यह उस अनावश्यक तर्क से छुटकारा पाने का एक अच्छा तरीका है जो बाद में सॉफ्टवेयर पुनरावृत्तियों में घूम सकता है या नहीं।

+0

मैं आपसे सहमत हूं, लेकिन आईएमओ एक निश्चित सूची कार्यान्वयन से विस्तार करते समय एक व्यापार बंद है - एक अलग रणनीति पर स्विच करना संभव नहीं है, उदा। LinkedList के साथ ArrayList को प्रतिस्थापित करें। प्रतिनिधिमंडल एक और विकल्प होगा। – home

+0

@ होम सॉर्ट करें, कुछ ऐसी चीज को स्विच करना इतना आसान है जो किसी अन्य चीज को सरणीसूची में फैलाता है जो तब तक कुछ और विस्तार करता है जब तक कि इंटरफ़ेस बिल्कुल समान या कुछ हद तक नजदीकी हों। –

+0

फिर से सहमत हुए। विरासत पर संरचना के लिए +1 – home

0

केवल तभी होगा यदि आप इस कोड का पुन: उपयोग करने के लिए जाते हैं और आपको याद नहीं है कि आपने ArrayList क्लास को ओवरराइड कर लिया है, तो पूरी तरह से टिप्पणी करना सुनिश्चित करें।

1

मुझे नहीं लगता कि यह एक अच्छा अभ्यास है। एक यूटिल-क्लास में दो पैरामीटर लेते हुए एक यूटिल-विधि लिखने पर विचार करें: सरणी सूची और वह वस्तु जिसे आप जोड़ना चाहते हैं। वहां आप जो कुछ भी चाहते हैं उसे देख सकते हैं और अपने कोड पर तर्क का पुन: उपयोग कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे