2011-09-05 14 views
15

मैं DRY और KISS सिद्धांतों का एक जुनूनी अनुयायी हूँ लेकिन पिछले सप्ताह मैं एक मामले में जहां दोनों एक दूसरे का खंडन करने लगते थे:चुंबन और सूखी टकराने जब

एक आवेदन मैं कर रहा था के लिए, मैं लागू करने के लिए किया था जो निम्नलिखित करता है समय के लिए एक पाश: ग्रुप ए

  • की एक सूची के तत्वों से अधिक

    1. पुनरावृति बी टाइप करें और उन्हें ग्रुप बी की एक सूची में डालने के लिए ग्रुप ए के तत्व को परिवर्तित

    यहाँ एक उदाहरण है:

    for (A a : listOfA) { 
        listOfB.add(BFactory.convertFromAToB(a)); 
    } 
    

    कोड के भीतर, मैं इस बारे में 4 बार ऐसा करने के लिए, एक प्रकार परिवर्तित (जैसे कि डी, ई आदि) एक और में। मैं उन प्रकारों को बदलने में सक्षम नहीं हूं जिन्हें मैं परिवर्तित करने वाला हूं, क्योंकि वे तृतीय पक्ष प्रकार हैं जिन्हें हमें ऐप में उपयोग करना है।

    तो हमने:

    convertAndCopy(listOfA, listOfB, new Function<A, B>() { 
        A apply(B b) { 
         return CFactory.convertFromBToC(b); 
        } 
    }); 
    
    :

    private interface Function<S, T> { 
        T apply(S s); 
    } 
    
    public <S, T> void convertAndCopy(List<S> src, List<T> dst, Function<S, T> f) { 
        for (S s : src) { 
         dst.add(f.apply(s)); 
        } 
    } 
    

    एक कॉल इस तरह दिखता है:

    for (A a : listOfA) { 
        listOfB.add(BFactory.convertFromAToB(a)); 
    } 
    
    for (C a : listOfC) { 
        listOfB.add(DFactory.convertFromCToD(c)); 
    } 
    
    ... 
    

    तो, सूखा का उल्लंघन नहीं करने के लिए, मैं एक सामान्य समाधान के साथ आया था

    अब, जबकि यह DRY के संदर्भ में बेहतर है, मुझे लगता है कि यह KISS का उल्लंघन करता है, क्योंकि इस समाधान को समझना बहुत मुश्किल है और loops के लिए डुप्लिकेट की तुलना में।

    तो, क्या यह DRY बनाम KISS है? इस संदर्भ में किस पक्ष का पक्ष लेना है?

    संपादित

    बस स्पष्ट होना, वर्ग के बारे में मैं बात कर रहा हूँ एक एडाप्टर है, जो हमारे अपने प्रतिनिधियों कार्यान्वयन के लिए एक विरासत व्यवस्था करने के लिए कहते हैं, रास्ते में हमारे अपने प्रकार में विरासत परिवर्तित है। मेरे पास विरासत प्रकारों को बदलने का कोई साधन नहीं है, न ही मैं अपने प्रकार बदल सकता हूं (जो एक्सएमएल-स्कीमा-जेनरेटेड हैं)।

  • +7

    कीवर्ड: जावा सूखी चुंबन - इसे प्यार करता हूँ! – hawkeye

    +1

    "शुष्क" का क्या अर्थ है? आह, जवाब यह कहता है, मुझे लगता है कि खुद को दोहराना नहीं है। –

    +0

    @Angel, sry मैं बाद में संदर्भ जोड़ दूंगा :-)। – helpermethod

    उत्तर

    15

    या तो ठीक है।

    लूप के साथ, आप वास्तव में खुद को दोहरा नहीं रहे हैं, क्योंकि दोहराए जाने वाले एकमात्र भाग "वाक्य रचनात्मक अव्यवस्था" (और आपके मामले में बहुत अधिक नहीं हैं)। आप "एप्लिकेशन तर्क" कोड दोहराना/डुप्लिकेट नहीं कर रहे हैं।

    यदि आपको "फ़ंक्शन" शैली पसंद है, तो शायद गुवा लाइब्रेरी का उपयोग करें (जिसमें फ़ंक्शन इंटरफ़ेस और संग्रह पर उनके साथ काम करने वाले कई सहायक तरीके हैं)। वह DRY है (क्योंकि आप स्वयं को दोहराना नहीं चाहते हैं, और पहले से मौजूद कोड का पुनः उपयोग करें), और अभी भी KISS (क्योंकि वे अच्छी तरह से समझ गए पैटर्न हैं)।

    +0

    +1 Thx, पूरी तरह से Guava के बारे में भूल जाओ! – helpermethod

    9

    डीआरवाई और केआईएसएस जैसे सामान्य सिद्धांत हर समय काम नहीं करते हैं।

    IMO, जवाब हठधर्मिता (कम से कम इस समस्या के लिए) भूल जाते हैं, और क्या आप सबसे अच्छा/सबसे पठनीय समाधान देता है के बारे में सोचना है।

    यदि दोहराया एक्स 4 कोड आसान को समझते हैं और एक रखरखाव बोझ नहीं है (`आप इसे एक बहुत बदलने की जरूरत है क्योंकि) ने अपने सही समाधान,।

    (और थिलो के जवाब सही भी है ... IMO)

    12

    आप केवल अपने पूरे आवेदन में यह 4 बार क्या करना है, और रूपांतरण वास्तव में के रूप में अपने उदाहरण के रूप में तुच्छ है, तो मैं लिख 4 का चयन करेंगे जेनेरिक समाधान पर किसी भी समय loops के लिए।

    पठनीयता है कि जेनेरिक समाधान का उपयोग करने से एक बहुत ग्रस्त है और आप वास्तव में इसे से कुछ भी हासिल नहीं है।

    +4

    इस मामले में आपको DRY से इतना लाभ नहीं मिलता है: आपके पास कोई प्रमुख कोड कारक नहीं है; आप शायद खुद को दोहराने से पेश नहीं किया जा सकता है। आप अभी भी खुद को दोहराते हैं क्योंकि आपको "नया फ़ंक्शन {एक्स लागू (वाई वाई) {वापसी CFactory.convertFromYToX (y); }} लिखना है" हर समय। मैं इस बार KISS चाहता हूँ। – ysdx

    4

    मुझे लगता है कि यह नहीं है कि केआईएसएस और डीआरवाई एक-दूसरे से विरोधाभास करते हैं। मैं कहूंगा कि जावा आपको खुद को दोहराने के दौरान सादगी व्यक्त करने की अनुमति नहीं देता है।

    सबसे पहले यदि आप List<A> से List<B> में परिवर्तित करने के लिए उचित ढंग से नामित विधियों को पेश करते हैं और इसलिए लूप को दोहराने के बजाय हर बार यह डीआईवाई होगा जबकि अभी भी केआईएसएस शेष है।

    लेकिन मैं सलाह दूंगा कि वैकल्पिक भाषाओं को देखने के लिए जो आपको डीआईवाई की पूर्ण odvantage लेने की अनुमति देता है, जबकि अभी भी KISS को बढ़ावा देता है, उदा। स्काला में:

    val listOfB = listOfA map convertAtoB 
    val listOfC = listOfB map convertBtoC 
    val listOfD = listOfC map convertCtoD 
    

    कहाँ convertAtoB एक समारोह ग्रुप ए के एक आइटम लेने और बी लौटने है:

    def convertAtoB(a: A): B = //... 
    

    या आप भी इन map कॉल श्रृंखला कर सकते हैं।

    4

    आप CFactory में रूपांतरण समारोह के लिए कदम सकता है:

    convertAndCopy(listOfA, listOfB, CFactory.getConverterFromAToB()); 
    

    कोड काफी पठनीय/सरल इस तरह से है और आप कोड पुन: उपयोग को बढ़ावा देने के (शायद आप किसी अन्य संदर्भ में बाद में कनवर्टर वस्तु का उपयोग करने की आवश्यकता होगी)।

    कार्यान्वयन:

    public <S, T> void convertAndCopy(List<A> listofA, List<B> listOfB, Function<A, B> f) { 
        listOfB.addAll(Collections2.transform(listOfA,f)); 
    } 
    

    (अमरूद Iterators का उपयोग)।

    मैं भी यकीन है कि तुम यहाँ सुखा लेना चाहिए नहीं कर रहा हूँ, आप सीधे इस्तेमाल कर सकते हैं:

    listOfB.addAll(Collections2.transform(listOfA,CFactory.getConverterFromAToB())); 
    
    +0

    +1 यह वास्तव में एक अच्छा विचार है :-)। – helpermethod