2015-06-20 11 views
7

के डिफ़ॉल्ट मान को कैसे प्रबंधित करें मैं एक कक्षा बना रहा हूं जिसमें मैं व्यक्ति कहलाता हूं। व्यक्ति के क्षेत्र में से एक 'उपनाम' है जो ArrayList<String> है। आखिरकार उपनाम को निम्नलिखित तर्क के अनुसार उपयोगकर्ता को प्रदर्शित किया जाएगा: यदि व्यक्ति के उपनाम हैं तो उन्हें [Finch, Wren, Admin, etc...] के रूप में प्रदर्शित किया जाना चाहिए, अन्यथा UNKNOWN प्रदर्शित होना चाहिए। अब तक मैं तीन तरीकों में से एक में इस लागू करने की कोशिश की है:एक ArrayList

  1. व्यक्ति विधि getAliases() जो केवल ArrayList की एक प्रति रिटर्न के रूप में शामिल हैं। वांछित व्यवहार को लागू करने के लिए कॉलर रिक्त सरणी के लिए जांच करता है।

  2. व्यक्ति में aliasesToString() विधि शामिल है जिसे वांछित स्ट्रिंग का उत्पादन करने के लिए कहा जा सकता है।

  3. ArrayList<String> का उपयोग करने के बजाय, उपनाम DefaultableArrayList<T> का कार्यान्वयन है। यह वर्ग ArrayList को बढ़ाता है और टाइप टी के साथ एक डिफ़ॉल्ट मान रखता है। toString() विधि वांछित स्ट्रिंग का उत्पादन करने के लिए अतिप्रवाह है। वांछित व्यवहार का उत्पादन करने के लिए एप्लिकेशन some_person.getAliases().toString() पर कॉल करता है।

    public class DefaultableArrayList<T> extends ArrayList<T> { 
    
        private static final long serialVersionUID = -6735356930885363889L; // Auto-generated 
        private final T defaultElement; 
    
    
        public DefaultableArrayList(T defaultElement) { 
         super(); 
         this.defaultElement = defaultElement; 
        } 
    
    
        public DefaultableArrayList(Collection<? extends T> c, T defaultElement) { 
         super(c); 
         this.defaultElement = defaultElement; 
        } 
    
    
        public DefaultableArrayList(int initialCapacity, T defaultElement) { 
         super(initialCapacity); 
         this.defaultElement = defaultElement; 
        } 
    
    
        public T getDefaultElement() { 
         return defaultElement; 
        } 
    
    
        @Override 
        public String toString() { 
         if (!isEmpty()) { 
          return super.toString(); 
    
         } else { 
          return defaultElement.toString(); 
         } 
        } 
    } 
    

    क्या मुझे विकल्प 2 के बारे में चिंताओं और 3 कि मैं OOP दिशानिर्देशों का उल्लंघन, जबकि अनावश्यक जटिलता जोड़ने हो सकता है:

नीचे विकल्प 3 के अपने कार्यान्वयन है। क्या व्यक्ति वास्तव में चिंतित होना चाहिए कि क्या कोई उपनाम नहीं है और क्या यह उपनाम के लिए यह समझ में आता है कि यह अंततः आवेदन में कैसे कार्यान्वित किया जाता है? मुझे लगता है कि मुझे कॉलर को रिक्त मामले को संभालने देना चाहिए। मुझे कौन सा विकल्प चुनना चाहिए कि मानक ओओपी डिज़ाइन दिशानिर्देशों को सर्वोत्तम रूप से पूरा किया जाए? या क्या कोई चौथा विकल्प है जिसे मैंने नहीं माना है?

उत्तर

6

पहला विकल्प सही है। मॉडल को प्रदर्शित होने के तरीके से चिंतित नहीं होना चाहिए।

आप एक अमीर एप्लिकेशन, वेब एप्लिकेशन या कंसोल एप्लिकेशन में उसी व्यक्ति और उसके उपनामों का प्रतिनिधित्व नहीं करेंगे।

यहां तक ​​कि किसी दिए गए एप्लिकेशन में, आप संभवतः एक ही मॉडल को विभिन्न तरीकों से प्रस्तुत करेंगे।

यदि आप अपने आवेदन को अंतर्राष्ट्रीयकृत करते हैं, तो आपको किसी अन्य चीज़ को "अज्ञात" बदलना होगा।

तो, बस सूची को वापस करें (या सूची का एक अपरिवर्तनीय vew), और प्रस्तुतिकरण परत प्रस्तुति तर्क के साथ सौदा दें। बीटीडब्ल्यू, toString() किसी एप्लिकेशन में ऑब्जेक्ट का प्रतिनिधित्व करने के लिए उपयोग की जाने वाली कार्यात्मक विधि से अधिक डिबगिंग सहायता है। अपने विकल्पों के माध्यम से

2

लेट्स की पैदल दूरी पर:

व्यक्ति विधि getAliases() जो केवल ArrayList देता है के रूप में शामिल हैं। वांछित व्यवहार को लागू करने के लिए कॉलर रिक्त सरणी के लिए जांच करता है।

कॉलर कोड कैसा दिखता है?

if (!person.getAliases().isEmpty()) { //Print aliases } 

यह थोड़ा बदसूरत और अपठनीय दिखता है।यदि आप इस विकल्प के साथ जाना चाहते हैं, कम से कम आप कर सकते हैं Person जो अनिवार्य रूप से आप के लिए जांच करता है में एक hasAliases विधि जोड़ने है और ग्राहक अधिक पठनीय कोड बनाता है: एक बहुत क्लीनर और अभी बहुत कुछ है कि

if (person.hasAliases()) { //Print aliases } 

पठनीय कोड।

व्यक्ति में विधि उपनाम ToString() शामिल है जिसे वांछित स्ट्रिंग का उत्पादन करने के लिए कहा जा सकता है।

Person हालांकि आत्मनिर्भर होना एक बुरा नहीं है।

if (person.hasAliases()) { 
    List<String> aliases = person.getAliases(); 
    StringBuilder aliaseString = new StringBuilder(""); 
    for (String alias : aliases) { 
     aliasString.append(aliases); 
    } 
} 
इसके बजाय ArrayList का उपयोग करने का

, उपनाम इस तरह के एक सरल कार्य के लिए एक overkill है कि DefaultableArrayList

के एक कार्यान्वयन है: सभी क्लाइंट कोड करना है कि कॉल person.aliasesToString() बजाय कर रही है।

तो आप किस दृष्टिकोण के साथ जाते हैं? यह आपकी समग्र आवश्यकता पर निर्भर करता है। यदि आपके पास अलग-अलग ग्राहक/UI हैं जो उपनामों के साथ अलग-अलग चीजें करना चाहते हैं, तो विकल्प 1 सबसे अच्छा होगा। यदि आपके पास एक ऐसा ग्राहक है जो हमेशा एक निश्चित तरीके से उपनाम मुद्रित करना चाहता है, तो विकल्प 2 बेहतर विकल्प होगा।

2

मुझे लगता है कि सबसे आसान तरीका अक्सर अच्छी शैली होती है। यही है, कुछ सरल करने पर कोड को प्राप्त करने वाला आमतौर पर इसका मतलब है कि शैली भटक रही है। इसलिए, विकल्प 1 इसे लागू करने के लिए एक ठोस तरीका की तरह दिखता है। क्षेत्र को वापस या प्रिंट करने के लिए getAliases() का उपयोग करना काफी मानक है। साथ ही, आप रिक्त सरणी के लिए चेक लागू कर सकते हैं और उस उदाहरण में UNKNOWN को वापस या प्रिंट कर सकते हैं। अन्यथा, और ArrayList toString() सामग्री बनाने की देखभाल करेगा।

2

विकल्प 3 एक ओवरकिल है। मैं ऐसे छोटे जोड़े गए मूल्य के लिए ArrayList का विस्तार नहीं करूंगा।

विकल्प 1 और विकल्प 2 के बीच चयन करना इस बात पर निर्भर करता है कि List के लिए अन्य अनुमानित उपयोग getAliases() द्वारा किए गए हैं, इसके स्ट्रिंग प्रस्तुति को प्रदर्शित करने के अलावा।

aliasesToString() विधि के साथ मैं केवल नकारात्मक पक्ष देखता हूं, यह धारणा है कि व्यक्ति वर्ग के सभी उपयोगकर्ता उपनामों को उसी तरह प्रदर्शित करेंगे।

यदि आप getAliases() विधि के साथ जाते हैं, तो मैं उस सूची की प्रतिलिपि या उस सूची के सरणी प्रतिनिधित्व को वापस करने के लिए उस विधि को प्राथमिकता दूंगा। इसका कारण यह है कि आप अपनी व्यक्तिगत कक्षा के उपयोगकर्ता को getAliases() द्वारा लौटाई गई सूची को म्यूट करके व्यक्ति उदाहरण को म्यूट करने से रोकते हैं।

+2

मैं एक अपरिवर्तनीय दृश्य वापस करना पसंद करूंगा: 'संग्रह .unmodifiableList (उपनाम)'। –

+0

@JBNizet 'संग्रह .unmodifiableList (उपनाम) 'एक अच्छा विकल्प है। यह मूल इंस्टेंस सदस्य को संशोधित होने से बचाता है और यह विधि के कॉलर को स्पष्ट करता है कि वे उपनाम की सूची को म्यूट करके व्यक्ति उदाहरण को म्यूट नहीं कर सकते हैं। – Eran

+0

हां, क्षमा करें, मेरा मतलब यह नहीं था कि मैं प्रत्यक्ष संदर्भ वापस कर दूंगा। वह एक निरीक्षण था। – Helios