पूर्वता क्या होनी चाहिए: YAGNI या अच्छा डिज़ाइन?


76

किस बिंदु पर YAGNI को अच्छी कोडिंग प्रथाओं के विरुद्ध और इसके विपरीत होना चाहिए ? मैं काम पर एक परियोजना पर काम कर रहा हूं और धीरे-धीरे अपने सहकर्मियों को अच्छे कोड मानकों को पेश करना चाहता हूं (वर्तमान में कोई भी नहीं है और सब कुछ बस कविता या कारण के बिना एक साथ हैक किया गया है), लेकिन कक्षाओं की एक श्रृंखला बनाने के बाद (हम टीडीडी मत करो, या दुख की बात है कि किसी भी तरह की इकाई परीक्षण) मैंने एक कदम पीछे ले लिया और सोचा कि यह YAGNI का उल्लंघन कर रहा है क्योंकि मैं बहुत निश्चित रूप से जानता हूं कि हमें इन वर्गों में से कुछ का विस्तार करने की आवश्यकता नहीं है।

यहां इसका एक ठोस उदाहरण है कि मेरा क्या मतलब है: मेरे पास संग्रहीत प्रक्रियाओं के सेट को लपेटने वाली एक डेटा एक्सेस परत है, जो मूल सीआरयूडी कार्यों के साथ अल्पविकसित रिपोजिटरी-शैली पैटर्न का उपयोग करता है। चूंकि मेरे मुट्ठी भर वर्गों की जरूरत है, इसलिए मैंने अपने रिपॉजिटरी के लिए एक सामान्य इंटरफ़ेस तैयार किया है IRepository। हालाँकि, मैंने तब एक "मार्कर" इंटरफ़ेस (यानी इंटरफ़ेस जो किसी भी नई कार्यक्षमता को नहीं जोड़ता है) को प्रत्येक प्रकार के रिपॉजिटरी (उदाहरण के लिए ICustomerRepository) और कंक्रीट क्लास को लागू करता है। मैंने एक ही काम किया है DataReaders / DataSets से व्यावसायिक वस्तुओं का निर्माण करने के लिए एक कारखाने के कार्यान्वयन के साथ, संग्रहीत प्रक्रिया द्वारा लौटाया गया; मेरे रिपॉजिटरी वर्ग का हस्ताक्षर कुछ इस तरह दिखता है:

public class CustomerRepository : ICustomerRepository
{
    ICustomerFactory factory = null;

    public CustomerRepository() : this(new CustomerFactory() { }

    public CustomerRepository(ICustomerFactory factory) {
        this.factory = factory;
    }      

    public Customer Find(int customerID)
    {
        // data access stuff here
        return factory.Build(ds.Tables[0].Rows[0]);
    }
}

यहां मेरी चिंता यह है कि मैं YAGNI का उल्लंघन कर रहा हूं क्योंकि मैं 99% निश्चितता के साथ जानता हूं कि CustomerFactoryइस रिपॉजिटरी को कंक्रीट के अलावा कुछ भी देने का कोई कारण नहीं है; चूँकि हमारे पास इकाई परीक्षण नहीं MockCustomerFactoryहैं, इसलिए मुझे या इसी तरह की चीजों की आवश्यकता नहीं है , और इतने सारे इंटरफेस होने से मेरे सहकर्मी भ्रमित हो सकते हैं। दूसरी ओर, कारखाने के एक ठोस कार्यान्वयन का उपयोग डिजाइन गंध की तरह लगता है।

क्या उचित सॉफ्टवेयर डिजाइन के बीच समझौता करने के लिए एक अच्छा तरीका है और समाधान का समर्थन नहीं करना है? मैं सवाल कर रहा हूँ कि क्या मुझे "सिंगल इम्प्लिमेंटेशन इंटरफेस" की ज़रूरत है या अगर मैं थोड़ी अच्छी डिज़ाइन का त्याग कर सकता हूँ और उदाहरण के लिए, बेस इंटरफ़ेस और फिर सिंगल कंक्रीट, और प्रोग्रामिंग की चिंता नहीं करता यदि कार्यान्वयन ऐसा है जो कभी भी उपयोग किया जाएगा।


17
आप कहते हैं, "चूंकि हमारे पास यूनिट परीक्षण नहीं हैं इसलिए मुझे मॉकएक्स की आवश्यकता नहीं है" जो स्वाभाविक रूप से "मुझे IX की आवश्यकता नहीं है, मुझे केवल एक्स की आवश्यकता है"। मैं फ्लिप कि चारों ओर, तथ्य यह है कि आप इकाई परीक्षण की जरूरत नहीं है तथ्य यह है कि आप नौवीं और MockX की जरूरत है, क्योंकि इन बातों से आपको मदद मिलेगी पर प्रकाश डाला गया है इकाई परीक्षण। कोई परीक्षण नहीं होने की वास्तविकता को स्वीकार न करें, इसे एक अस्थायी समस्या के रूप में मानें जो कि समय पर (शायद एक अच्छा, लंबा) समय में सुधार होगा।
एंथनी पेग्राम

10
भले ही यह इसे Google के लिए तुच्छ हो, लेकिन किसी को यह उल्लेख करना चाहिए कि YAGNI का अर्थ है "आपको इसकी आवश्यकता नहीं है"
thedaian

1
मुझे लगता है कि यदि आप इस तरह से नई कक्षाएं लिख रहे हैं, तो आप कुछ यूनिट परीक्षण जोड़ना चाहेंगे। भले ही आपके सहकर्मी उन्हें नहीं चलाएंगे। कम से कम बाद में आप कह सकते हैं, "देखो! मेरी इकाई परीक्षणों ने इसे पकड़ लिया जब आपने मेरा कोड तोड़ा! देखें कि इकाई परीक्षण कितने महान हैं!" उस स्थिति में, इसे नकली बनाना यहाँ सार्थक हो सकता है। (हालांकि, मैं इसे पसंद करूँगा अगर ऑब्जेक्ट को एक इंटरफ़ेस को परिभाषित किए बिना मज़ाक किया जा सकता है)
विंस्टन एवर्ट

क्या यूनिट परीक्षण मुझे एक नकली रूपरेखा बनाने (या उपयोग) के लिए बाध्य नहीं करेंगे ताकि मैं लाइव संग्रहीत प्रक्रियाओं को न मारूं? यही मुख्य कारण है कि मैं परीक्षण नहीं जोड़ता हूं - हमारे पास उत्पादन डेटाबेस की एक स्थानीय प्रतिलिपि है जिसे हम परीक्षण करते हैं और उसके खिलाफ कोड लिखते हैं।
वेन मोलिना

3
@ एंथनी और क्या हमेशा यह कहना कि वह जिस जटिल जटिलता को खत्म करता है, उसका मजाक उड़ाता है? मॉकिंग एक अच्छा उपकरण है, लेकिन इसकी उपयोगिता को लागतों के खिलाफ भी भारित किया जाना चाहिए और कभी-कभी पैमाने को अप्रत्यक्ष रूप से अधिकता से दूसरे तरीके से इत्तला दे दी जाती है। ज़रूर, अतिरिक्त जटिलता के साथ मदद करने के लिए उपकरण हैं लेकिन वे जटिलता को दूर नहीं करेंगे। किसी भी रूप में "सभी कीमत पर परीक्षण" के इलाज की बढ़ती प्रवृत्ति प्रतीत होती है। मेरा मानना ​​है कि यह गलत है।
कोनराड रुडोल्फ

जवाबों:


75

क्या उचित सॉफ्टवेयर डिजाइन के बीच समझौता करने के लिए एक अच्छा तरीका है और समाधान का समर्थन नहीं करना है?

YAGNI।

मैं अच्छे डिजाइन का एक सा त्याग कर सकता था

मिथ्या धारणा।

और आधार इंटरफ़ेस और फिर एकल कंक्रीट,

वह "बलिदान" नहीं है। यही कारण है कि है अच्छे डिजाइन।


72
पूर्णता तब प्राप्त होती है, जब जोड़ने के लिए और कुछ नहीं होता है, लेकिन जब लेने के लिए कुछ नहीं बचता है। एंटोनी डी सेंट-
एक्सुपरी

5
@ न्यूटोपियन: एप्पल के नवीनतम उत्पादों के बारे में लोगों की मिश्रित भावनाएं हैं। :)
रॉय टिंकर

14
मुझे इस तरह के जवाबों से बड़ी समस्या है। क्या "X सच है क्योंकि Y यह कहता है, और Y समुदाय द्वारा अच्छी तरह से समर्थित है" मान्य तर्क? अगर वास्तविक जीवन में कोई व्यक्ति YAGNI के खिलाफ लामबंद हो जाता है, तो क्या आप उसे इस जवाब को तर्क के रूप में दिखाएंगे?
वीएमवी

2
@vemv। यहां कोई भी YAGNI के खिलाफ हंगामा नहीं कर रहा है। सभी S.Lott ने कहा कि 2 योग्य लक्ष्यों के बीच ओपी का कथित विरोधाभास एक गलती है। BTW, क्या आप आज के सॉफ्टवेयर की दुनिया में किसी भी सक्रिय डेवलपर को जानते हैं जो YAGNI के खिलाफ होगा? यदि आप वास्तविक परियोजनाओं पर काम कर रहे हैं, तो आप जानते हैं कि आवश्यकताएं लगातार बदल रही हैं और उपयोगकर्ता और प्रबंधक आम तौर पर यह नहीं जानते हैं कि वे क्या करते हैं या नहीं चाहते हैं जब तक आप इसे उनके सामने नहीं रखते हैं। आवश्यक को लागू करना काम की योजना है - क्यों समय, ऊर्जा और पैसे बर्बाद करना (या अपनी नौकरी जोखिम) कोड लिखकर जो भविष्य की भविष्यवाणी करने की कोशिश करता है?
वेक्टर

6
मेरी बात YAGNI के बारे में नहीं है - यह उत्तर गुणवत्ता के बारे में है। मैं यह नहीं कहता कि कोई व्यक्ति विशेष रूप से रंटिंग कर रहा था, यह मेरे तर्क का हिस्सा था। कृपया इसे फिर से पढ़ें।
वीएमवी

74

ज्यादातर मामलों में, ऐसे कोड से बचना चाहिए जिनकी आपको आवश्यकता नहीं है, बेहतर डिज़ाइन की ओर ले जाता है । सबसे अधिक बनाए रखने योग्य और भविष्य-प्रूफ डिज़ाइन वह है जो आवश्यकताओं को पूरा करने वाले सरल, सरल कोड की सबसे छोटी राशि का उपयोग करता है।

सबसे सरल डिजाइन विकसित करने के लिए सबसे आसान हैं। कुछ भी नहीं की तरह स्थिरता को मारता है, अतिरंजित अमूर्त परतों।


8
मुझे लगता है कि 'YAGNI कोड से बचना' अनावश्यक रूप से अस्पष्ट है। इसका मतलब यह हो सकता है कि आप कोड की जरूरत नहीं है या कोड है कि YAGNI सिद्धांत का पालन करता है । (सी एफ 'KISS कोड')
sehe

2
@ यह: यह अस्पष्ट नहीं है (जबकि "YAGNI सिद्धांत का पालन करता है" एकमुश्त आत्म-विरोधाभासी है) यदि आप इसे बख्शते हैं: तो "You-aint’t-if-need-it-code" क्या मतलब हो सकता है लेकिन कोड का मतलब है कि कोड आप की जरूरत नहीं है?
माइकल बोर्गवर्ड्ट

1
मैं इस उत्तर को एक बड़े फ़ॉन्ट में मुद्रित करने जा रहा हूं और इसे लटका दूंगा जहां सभी वास्तुकला अंतरिक्ष यात्री इसे पढ़ सकते हैं। +1!
kirk.burleson

1
+1। मुझे अभी भी याद है कि मेरा पहला कॉर्पोरेट प्रोजेक्ट मुझे कुछ नई सुविधाओं का समर्थन और जोड़ने के लिए दिया गया था। पहली बात मैंने बिना किसी कार्यक्षमता को खोए 40,000 लाइन प्रोग्राम से बेकार कोड की 32,000 लाइनों को हटा दिया था । इसके तुरंत बाद मूल प्रोग्रामर को निकाल दिया गया था।
ईजे ब्रेनन

4
@vemv: "बेकार" के रूप में "वर्तमान में उपयोग नहीं किया जा रहा है, केवल तुच्छ को छोड़कर", यानी YAGNI का मामला। और "अतिरंजित" "खराब" की तुलना में थोड़ा अधिक विशिष्ट है। विशेष रूप से इसका अर्थ है "ठोस, वर्तमान आवश्यकताओं के बजाय सैद्धांतिक अवधारणाओं या संभावित आवश्यकताओं की कल्पना के कारण जटिलता"।
माइकल बोर्गवर्ड

62

YAGNI और SOLID (या कोई अन्य डिज़ाइन पद्धति) परस्पर अनन्य नहीं हैं। हालांकि, वे निकट-ध्रुवीय विरोधी हैं। आपको 100% का पालन करने की आवश्यकता नहीं है, लेकिन कुछ देना और लेना होगा; जितना अधिक आप एक स्थान पर एक वर्ग द्वारा उपयोग किए जाने वाले उच्च-अमूर्त पैटर्न को देखते हैं, और YAGNI कहते हैं और इसे सरल करते हैं, कम ठोस डिजाइन बन जाता है। रिवर्स सच भी हो सकता है; विकास में कई बार, एक डिज़ाइन को "विश्वास पर" सॉलिडली लागू किया जाता है; आप यह नहीं देखते हैं कि आपको इसकी आवश्यकता कैसे होगी, लेकिन आपके पास सिर्फ एक कूबड़ है। यह सच हो सकता है (और अधिक अनुभव होने की संभावना अधिक सच है), लेकिन यह आपको एक स्लैप-डैश "डू इट लाइट" दृष्टिकोण के रूप में तकनीकी ऋण में डाल सकता है; DIL "स्पेगेटी कोड" कोडबेस के बजाय, आप "Lasagna कोड" के साथ समाप्त हो सकते हैं, केवल एक विधि या नए डेटा क्षेत्र को जोड़ने वाली इतनी सारी परतें होने के कारण केवल एक कार्यान्वयन के साथ सेवा प्रॉक्सी और शिथिल-युग्मित निर्भरता के माध्यम से लुप्त होने की एक दिन की लंबी प्रक्रिया बन जाती है। या आप "रैवियोली कोड" के साथ समाप्त हो सकते हैं, जो इस तरह के छोटे काटने के आकार के टुकड़ों में आता है, जो वास्तुकला में ऊपर, नीचे, बाएं या दाएं घूमते हुए आपको 3 लाइनों के साथ 50 तरीकों से ले जाता है।

मैंने इसे अन्य उत्तरों में कहा है, लेकिन यहां यह है: पहले पास पर, इसे काम करें। दूसरे पास पर, इसे सुरुचिपूर्ण बनाएं। तीसरे पास पर, इसे SOLID करें।

इसे तोड़कर:

जब आप पहली बार कोड की एक पंक्ति लिखते हैं, तो उसे बस काम करना होता है। इस बिंदु पर, आप सभी जानते हैं, यह एक-बंद है। तो, आपको 2 और 2 को जोड़ने के लिए एक "हाथीदांत-टॉवर" वास्तुकला के निर्माण के लिए कोई शैली अंक नहीं मिलता है और जो आप करते हैं, उसे करें और मान लें कि आप इसे फिर कभी नहीं देखेंगे।

अगली बार जब आपका कर्सर कोड की उस पंक्ति में जाता है, तो आपने अपनी परिकल्पना को उस समय से अस्वीकार कर दिया है जब आपने इसे लिखा था। आप उस कोड को फिर से देख रहे हैं, संभवत: इसे विस्तारित करने या इसे कहीं और उपयोग करने के लिए, इसलिए यह एकतरफा नहीं है। अब, DRY जैसे कुछ बुनियादी सिद्धांत (खुद को दोहराएं नहीं) और कोड डिजाइन के लिए अन्य सरल नियम लागू किए जाने चाहिए; निकालने के तरीके और / या बार-बार कोड के लिए लूप बनाते हैं, सामान्य शाब्दिक या भावों के लिए चर निकालें, हो सकता है कि कुछ टिप्पणियां जोड़ें, लेकिन कुल मिलाकर आपके कोड को स्व-दस्तावेज़ होना चाहिए। अब, आपका कोड अच्छी तरह से व्यवस्थित है, अगर अभी भी शायद कसकर-युग्मित है, और कोई भी इसे देख रहा है, तो आप आसानी से सीख सकते हैं कि आप कोड पढ़कर क्या कर रहे हैं, इसके बजाय लाइन-बाय-लाइन को ट्रेस करना।

तीसरी बार जब आपका कर्सर उस कोड में प्रवेश करता है, तो यह संभवतः एक बड़ी बात है; आप या तो इसे फिर से बढ़ा रहे हैं या यह कोडबेस में कम से कम तीन अलग-अलग स्थानों में उपयोगी हो गया है। इस बिंदु पर, यह एक कुंजी है, यदि कोर नहीं है, तो आपके सिस्टम का तत्व, और इस तरह से आर्किटेक्चर होना चाहिए। इस बिंदु पर, आपके पास आमतौर पर इस बात का भी ज्ञान होता है कि अब तक इसका उपयोग कैसे किया गया है, जो आपको उन डिजाइनों और किसी भी नए को कारगर बनाने के लिए डिज़ाइन के आर्किटेक्ट के बारे में अच्छे निर्णय लेने की अनुमति देगा। अब एसओएलआईडी नियमों को समीकरण में प्रवेश करना चाहिए; विशिष्ट उद्देश्यों के साथ कोड रखने वाली कक्षाएं निकालें, समान उद्देश्यों या कार्यक्षमता वाले किसी भी वर्ग के लिए सामान्य इंटरफेस को परिभाषित करें, कक्षाओं के बीच शिथिल-युग्मित निर्भरताएं सेट करें, और निर्भरता को ऐसे डिज़ाइन करें कि आप उन्हें आसानी से जोड़, निकाल या स्वैप कर सकें।

इस बिंदु से, क्या आपको इस कोड को आगे बढ़ाने, फिर से लागू करने या फिर से उपयोग करने की आवश्यकता है, यह सभी अच्छी तरह से पैक किया गया है और "ब्लैक बॉक्स" प्रारूप में हम सभी जानते हैं और प्यार करते हैं; इसे जहाँ कहीं भी आपकी आवश्यकता हो, वहां प्लग करें या थीम के नए कार्यान्वयन के रूप में थीम पर एक नया बदलाव जोड़ें, ताकि उक्त इंटरफ़ेस का उपयोग बदले बिना हो सके।


मैं दूसरी अजीबता।
फिलिप डुपनोविक सिप

2
हाँ। जब मैंने पुन: उपयोग / विस्तार के लिए डिज़ाइन किया, तो मैंने पाया कि जब मैं इसका पुन: उपयोग या विस्तार करना चाहता था, तो यह एक अलग तरह से होगा जैसा मैंने अनुमान लगाया था। भविष्यवाणी कठिन है, विशेष रूप से भविष्य के विषय में। इसलिए मैं आपके 3-स्ट्राइक नियम का समर्थन करता हूं - उस समय तक, आपके पास एक उचित विचार है कि इसका पुन: उपयोग / विस्तार कैसे किया जाएगा। एनबी: एक अपवाद है यदि आप पहले से ही जानते हैं कि यह कैसे होगा (जैसे पिछले परियोजनाओं, डोमेन ज्ञान, या पहले से निर्दिष्ट)।
13ren

चौथे पास पर, इसे अद्भुत बनाएं।
रिचर्ड नील इलगन

@KeithS: ऐसा लगता है कि जॉन कार्मैक ने कुछ ऐसा ही किया: "क्वेक II का सोर्स कोड ... क्विक 1, क्वेक वर्ल्ड और क्वेकगेल को एक सुंदर कोड आर्किटेक्चर में एकीकृत करें।" fabiensanglard.net/quake2/index.php
13ren

+1 मुझे लगता है कि मैं उर नियम का नाम लूंगा: "प्रैक्टिकल रीफैक्टरिंग" :)
सोंगो

31

उन दोनों में से किसी के बजाय, मैं WTSTWCDTUAWCROT पसंद करता हूं?

(जो सबसे सरल बात हम कर सकते हैं वह उपयोगी है और हम गुरुवार को जारी कर सकते हैं?)

सरल चीजें मेरे काम करने की चीजों की सूची में हैं, लेकिन वे प्राथमिकता नहीं हैं।


8
वह संक्षिप्त नाम YAGNI सिद्धांत का उल्लंघन करता है :)
riwalk

2
मैंने अपनी ज़रूरत के अक्षरों का बिल्कुल उपयोग किया - कोई और अधिक और कोई कम नहीं। उस तरह, मैं मोजार्ट की तरह हूँ। हां। मैं मोज़ार्ट का मोज़ार्ट हूँ।
माइक शेरिल 'कैट रिकॉल'

4
मुझे कभी नहीं पता था कि मोज़ार्ट समरूप बनाने में भयानक था। मैं एक एसई साइट पर हर दिन कुछ नया सीखता हूं। : पी
कैमरून मैकफारलैंड

3
@ माइक शेरिल 'कैटेरॉल': हो सकता है कि कोई व्यक्ति WSTSTWCDTUWCROTAWBOF = "वह सबसे आसान काम जो हम कर सकते हैं, वह यह है कि हम इसे गुरुवार को जारी कर सकते हैं और शुक्रवार को नहीं टूटेंगे?" ;-)
जियोर्जियो

1
@ Stargazer712 नहीं :) यह POLA का उल्लंघन करता है।
v.oddou

25

YAGNI और अच्छे डिज़ाइन परस्पर विरोधी नहीं हैं। YAGNI भविष्य की जरूरतों का समर्थन करने वाला (नहीं) है। अच्छा डिजाइन पारदर्शी बनाने के बारे में है कि आपका सॉफ्टवेयर अभी क्या करता है और यह कैसे करता है।

क्या फैक्ट्री शुरू करने से आपका मौजूदा कोड सरल हो जाएगा? यदि नहीं, तो इसे न जोड़ें। यदि ऐसा होता है, उदाहरण के लिए जब आप परीक्षण जोड़ रहे हैं (जो आपको करना चाहिए!), इसे जोड़ें।

YAGNI भविष्य के कार्यों का समर्थन करने के लिए जटिलता को नहीं जोड़ने के बारे में है।
अच्छा डिजाइन सभी मौजूदा कार्यों का समर्थन करते हुए भी जटिलता को दूर करने के बारे में है।


15

वे संघर्ष में नहीं हैं, आपके लक्ष्य गलत हैं।

क्या आप पूरा करने का प्रयास कर रहे हैं?

आप गुणवत्ता सॉफ्टवेयर लिखना चाहते हैं, और यह करने के लिए कि आप अपने कोड आधार को छोटा रखना चाहते हैं और मुद्दे नहीं हैं।

अब हम संघर्ष तक पहुँचते हैं, अगर हम उन मामलों को नहीं लिखते हैं जो हम उन मामलों को नहीं लिखते हैं जिनका हम उपयोग नहीं करने जा रहे हैं?

यहां आपकी समस्या कैसी दिखती है।

यहाँ छवि विवरण दर्ज करें (किसी को भी दिलचस्पी है, इसे वाष्पित बादल कहते हैं )

तो, यह क्या चला रहा है?

  1. आप नहीं जानते कि आपको क्या चाहिए
  2. आप समय बर्बाद नहीं करना चाहते और अपने कोड को ब्लोट करें

हम इनमें से किसे हल कर सकते हैं? खैर, ऐसा लगता है कि समय बर्बाद नहीं करना चाहते हैं और ब्लोट कोड एक महान लक्ष्य है, और समझ में आता है। उस पहले के बारे में क्या? क्या हमें पता चल सकता है कि हमें कोड की आवश्यकता क्या है?

मैं काम पर एक परियोजना पर काम कर रहा हूं और धीरे-धीरे अपने सहकर्मियों को अच्छे कोड मानकों को पेश करना चाहता हूं (वर्तमान में कोई भी नहीं है और सब कुछ बस कविता या कारण के बिना एक साथ हैक किया गया है] [...] मैंने एक कदम पीछे लिया और सोचा कि यह YAGNI का उल्लंघन कर रहा है क्योंकि मैं बहुत निश्चितता के साथ जानता हूं कि हमें इनमें से कुछ वर्गों का विस्तार करने की आवश्यकता नहीं है।

आइए हम सब फिर से वाक्यांश

  • कोई कोड मानक नहीं
  • कोई परियोजना की योजना नहीं चल रही है
  • काउबॉय हर जगह अपनी लानत की चीज़ करते हैं (और आप जंगली जंगली पश्चिम में शेरिफ खेलने की कोशिश कर रहे हैं), यी हौ।

क्या उचित सॉफ्टवेयर डिजाइन के बीच समझौता करने के लिए एक अच्छा तरीका है और समाधान का समर्थन नहीं करना है?

आपको किसी समझौते की आवश्यकता नहीं है, आपको किसी ऐसे व्यक्ति की आवश्यकता है जो उस टीम का प्रबंधन करे जो सक्षम हो और जिसके पास पूरे प्रोजेक्ट का विजन हो। आपको किसी ऐसे व्यक्ति की ज़रूरत है जो आपकी ज़रूरत की चीज़ों की योजना बना सके, बजाय इसके कि आप उन सभी चीजों को फेंक दें जिनकी आपको ज़रूरत नहीं है क्योंकि आप भविष्य के लिए बहुत अनिश्चित हैं क्योंकि ... क्यों? मैं आपको बताऊंगा कि ऐसा क्यों है, क्योंकि आप सभी के बीच कोई भी योजना नहीं है। आप पूरी तरह से अलग समस्या को ठीक करने के लिए कोड मानकों को लाने की कोशिश कर रहे हैं। आपकी प्राथमिक समस्या जिसे आपको हल करने की आवश्यकता है, एक स्पष्ट रोडमैप और परियोजना है। एक बार जब आप ऐसा कर लेते हैं, तो आप कह सकते हैं "कोड मानक हमें एक टीम के रूप में और अधिक प्रभावी ढंग से इस लक्ष्य तक पहुंचने में मदद करते हैं," जो कि पूर्ण सत्य है लेकिन इस प्रश्न के दायरे से बाहर है।

एक प्रोजेक्ट / टीम मैनेजर प्राप्त करें जो ये काम कर सके। यदि आपके पास एक है, तो आपको उनसे एक नक्शे के लिए पूछना होगा और YAGNI समस्या को समझाना होगा कि मानचित्र प्रस्तुत नहीं हो रहा है। यदि वे स्थूल रूप से अक्षम हैं, तो योजना को स्वयं लिखें और कहें कि "यहां पर हमारी रिपोर्ट आपके लिए आवश्यक चीजों पर है, कृपया इसकी समीक्षा करें और हमें अपना निर्णय बताएं।"


हमारे पास एक नहीं, दुख की बात है। विकास प्रबंधक या तो मानकों / गुणवत्ता के बारे में तेजी से काम करने के बारे में अधिक चिंतित है, या मानक डेटा को बनाएगा जैसे कि कच्चे डेटासेट का उपयोग करना हर जगह कक्षाओं से सीधे लौटा, वीबी 6 स्टाइल कोडिंग और कोड-पीछे में डुप्लिकेट लॉजिक कॉपी और पेस्ट किए गए सभी के साथ ऊपर।
वेन मोलिना

यह ठीक है, यह थोड़ा धीमा होने वाला है, लेकिन आपको उनकी चिंताओं के बारे में बोलने की जरूरत है। समझाएं कि यह YAGNI / बेकार-कोड समस्या समय बर्बाद कर रही है, रोडमैप का सुझाव दें, उसे एक रोडमैप दें, यह समझाएं कि इससे काम तेजी से होगा। जब वह खरीदा जाता है, तो उन समस्याओं के साथ आते हैं जिनमें खराब मानकों के विकास की गति होती है, बेहतर लोगों को सुझाव दें। वे चाहते हैं कि परियोजना पूरी हो जाए, वे सिर्फ यह नहीं जानते हैं कि इस चीज को कैसे प्रबंधित किया जाए, आपको या तो उसे या उसके बच्चे को बदलने की आवश्यकता होगी ... या छोड़ दें।
गुप्त

एर्म ..... मुझे लगता है कि ड्राइविंग लक्ष्य 'आप एक अच्छा, मूल्यवान उत्पाद चाहते हैं' होगा?
sehe

@ वह उसका निर्णय नहीं है: पी।
गुप्त

3
बहुत बढ़िया जवाब। वह एक कठिन लड़ाई का सामना कर रहा है। इसे पूरा करना मुश्किल होगा यदि कोई प्रबंधन खरीद नहीं है और आप सही हैं कि प्रश्न समय से पहले है और वास्तविक समस्या का समाधान नहीं करता है।
सेठ स्पीयरमैन

10

यूनिट टेस्ट के साथ अपना कोड बढ़ाया जाना कभी भी YAGNI के तहत कवर नहीं होने वाला है, क्योंकि आपको इसकी आवश्यकता होगी । हालाँकि, मुझे विश्वास नहीं है कि एकल-कार्यान्वयन इंटरफ़ेस में आपके डिज़ाइन परिवर्तन वास्तव में कोड की कसौटी को बढ़ा रहे हैं क्योंकि CustomerFactory पहले से ही एक इंटरफ़ेस से विरासत में मिला है और किसी भी समय MockCustomerFactory के लिए स्वैप किया जा सकता है।


1
+1 केवल लौकिक लड़ाई और / या अच्छे डिजाइन और YAGNI के बीच प्रेम के बारे में वास्तविक समस्या के बारे में उपयोगी टिप्पणी के लिए।
psr

10

प्रश्न एक झूठी दुविधा प्रस्तुत करता है। YAGNI सिद्धांत का उचित अनुप्रयोग कुछ असंबंधित बात नहीं है। यह अच्छे डिजाइन का एक पहलू है। एसओएलआईडी के प्रत्येक सिद्धांत अच्छे डिजाइन के पहलू हैं। आप हमेशा किसी भी विषय में हर सिद्धांत को पूरी तरह से लागू नहीं कर सकते। वास्तविक दुनिया की समस्याओं ने आपके कोड पर बहुत सारी ताकतें डाल दीं, और उनमें से कुछ ने दिशाओं का विरोध किया। डिजाइन के सिद्धांतों को उन सभी के लिए जिम्मेदार होना चाहिए, लेकिन सिद्धांतों का कोई भी मुट्ठी भर सभी स्थितियों को फिट नहीं कर सकता है।

अब, आइए प्रत्येक सिद्धांत पर इस समझ के साथ नज़र डालें कि जब वे कभी-कभी विभिन्न दिशाओं में खींच सकते हैं, तो वे संघर्ष में निहित किसी भी तरह से नहीं होते हैं।

YAGNI की कल्पना डेवलपर्स को एक विशेष प्रकार के पुन: कार्य से बचने में मदद करने के लिए की गई थी: जो कि गलत चीज़ के निर्माण से आता है। यह हमें गलत या भविष्य में जरूरत के हिसाब से मान्यताओं या भविष्यवाणियों के आधार पर गलत निर्णय लेने से बचने के लिए मार्गदर्शन देकर करता है। सामूहिक अनुभव हमें बताता है कि जब हम ऐसा करते हैं, तो हम आमतौर पर गलत होते हैं। उदाहरण के लिए, YAGNI आपको बताएगा कि पुन: प्रयोज्यता के उद्देश्य के लिए एक इंटरफ़ेस न बनाएं , जब तक कि आप अभी यह नहीं जानते कि आपको कई कार्यान्वयनकर्ताओं की आवश्यकता है। इसी तरह YAGNI कहेंगे कि किसी एप्लिकेशन में एकल फ़ॉर्म को प्रबंधित करने के लिए "ScreenManager" न बनाएं जब तक कि आप अभी यह नहीं जानते कि आप एक से अधिक स्क्रीन रखने जा रहे हैं।

कई लोगों को लगता है कि इसके विपरीत, SOLID पुन: प्रयोज्यता, सामान्यता या अमूर्तता के बारे में नहीं है । SOLID का उद्देश्य है कि आप उस कोड को लिखने में मदद करें जो परिवर्तन के लिए तैयार है , बिना इस बारे में कुछ भी कहे कि वह विशिष्ट परिवर्तन क्या हो सकता है। एसओएलआईडी के पांच सिद्धांत बिल्डिंग कोड के लिए एक रणनीति बनाते हैं जो अत्यधिक सामान्य होने के बिना लचीला है, और भोले होने के बिना सरल है। SOLID कोड का उचित अनुप्रयोग अच्छी तरह से परिभाषित भूमिकाओं और सीमाओं के साथ छोटे, केंद्रित वर्ग का उत्पादन करता है। व्यावहारिक परिणाम यह है कि किसी भी आवश्यक आवश्यकताओं को बदलने के लिए, न्यूनतम संख्या में वर्गों को छूने की आवश्यकता है। और इसी तरह, किसी भी कोड परिवर्तन के लिए, अन्य वर्गों के माध्यम से "तरंग" की एक न्यूनतम राशि होती है।

आपके पास उदाहरण की स्थिति को देखते हुए, देखते हैं कि YAGNI और SOLID को क्या कहना पड़ सकता है। आप इस तथ्य के कारण एक सामान्य रिपॉजिटरी इंटरफ़ेस पर विचार कर रहे हैं कि सभी रिपॉजिटरी बाहर से समान दिखती हैं। लेकिन एक सामान्य, सामान्य इंटरफ़ेस का मूल्य किसी भी कार्यान्वयनकर्ता को यह जानने की आवश्यकता के बिना उपयोग करने की क्षमता है कि यह विशेष रूप से कौन सा है। जब तक आपके ऐप में कहीं ऐसा न हो जहां यह आवश्यक या उपयोगी होगा, YAGNI का कहना है कि ऐसा न करें।

देखने के लिए 5 ठोस सिद्धांत हैं। एस सिंगल रिस्पॉन्सिबिलिटी है। यह इंटरफ़ेस के बारे में कुछ नहीं कहता है, लेकिन यह आपके ठोस वर्गों के बारे में कुछ कह सकता है। यह तर्क दिया जा सकता है कि डेटा एक्सेस को संभालने के लिए सबसे अच्छा एक या अधिक अन्य वर्गों की जिम्मेदारी बन सकती है, जबकि रिपॉजिटरी की जिम्मेदारी एक निहित संदर्भ से अनुवाद करना है (CustomerRepository ग्राहक संस्थाओं के लिए स्पष्ट रूप से स्पष्ट कॉल में एक रिपॉजिटरी है। सामान्यीकृत डेटा एक्सेस API ग्राहक इकाई प्रकार निर्दिष्ट करता है।

O ओपन-क्लोज्ड है। यह ज्यादातर वंशानुक्रम के बारे में है। यह लागू होगा यदि आप अपने रिपॉजिटरी को सामान्य कार्यक्षमता को लागू करने वाले एक सामान्य आधार से प्राप्त करने की कोशिश कर रहे थे, या यदि आप विभिन्न रिपॉजिटरी से आगे प्राप्त करने की अपेक्षा करते हैं। लेकिन तुम नहीं हो, इसलिए यह नहीं है।

L, Liskov सबस्टिबिलिटी है। यदि आप सामान्य रिपॉजिटरी इंटरफ़ेस के माध्यम से रिपॉजिटरी का उपयोग करने का इरादा रखते हैं तो यह लागू होता है। यह निरंतरता सुनिश्चित करने के लिए इंटरफेस और कार्यान्वयन पर प्रतिबंध लगाता है और विभिन्न इम्पेलमेंटर्स के लिए विशेष हैंडलिंग से बचता है। इसका कारण यह है कि इस तरह की विशेष हैंडलिंग एक इंटरफ़ेस के उद्देश्य को कम करती है। इस सिद्धांत पर विचार करना उपयोगी हो सकता है, क्योंकि यह आपको सामान्य रिपॉजिटरी इंटरफ़ेस का उपयोग करने से दूर कर सकता है। यह YAGNI के मार्गदर्शन के साथ मेल खाता है।

मैं इंटरफ़ेस अलगाव है। यदि आप अपने रिपॉजिटरी में अलग-अलग क्वेरी ऑपरेशन जोड़ना शुरू करते हैं तो यह लागू हो सकता है। इंटरफ़ेस पृथक्करण लागू होता है जहां आप एक वर्ग के सदस्यों को दो सबसेट में विभाजित कर सकते हैं जहां एक का उपयोग कुछ उपभोक्ताओं द्वारा किया जाएगा और दूसरे का दूसरों द्वारा किया जाएगा, लेकिन कोई भी उपभोक्ता संभवतः दोनों सबसेट का उपयोग नहीं करेगा। मार्गदर्शन एक आम के बजाय दो अलग इंटरफेस बनाने के लिए है। आपके मामले में, यह संभव नहीं है कि अलग-अलग उदाहरणों को लाने और सहेजने का उपयोग उसी कोड द्वारा किया जाएगा जो सामान्य क्वेरी करते हैं, इसलिए उन लोगों को दो इंटरफेस में अलग करना उपयोगी हो सकता है।

डी डिपेंडेंसी इंजेक्शन है। यहाँ हम एस के समान बिंदु पर वापस आते हैं। यदि आपने डेटा एक्सेस API की अपनी खपत को एक अलग ऑब्जेक्ट में अलग कर दिया है, तो यह सिद्धांत कहता है कि उस ऑब्जेक्ट के उदाहरण को केवल नया करने के बजाय, आपको इसे बनाते समय पास करना चाहिए एक भंडार। इससे डेटा एक्सेस कंपोनेंट के जीवनकाल को नियंत्रित करना आसान हो जाता है, इससे आपकी रिपॉजिटरी के बीच संदर्भों को साझा करने की संभावना खुल जाती है, बिना इसे सिंगलटन बनाने के मार्ग पर जाने के।

यह नोट करना महत्वपूर्ण है कि अधिकांश SOLID सिद्धांत आवश्यक रूप से आपके ऐप के विकास के इस विशेष चरण में लागू नहीं होते हैं। उदाहरण के लिए, क्या आपको डेटा एक्सेस को तोड़ना चाहिए, यह इस बात पर निर्भर करता है कि यह कितना जटिल है, और क्या आप डेटाबेस से टकराये बिना अपने रिपॉजिटरी लॉजिक का परीक्षण करना चाहते हैं। ऐसा लगता है कि यह संभावना नहीं है (दुर्भाग्य से, मेरी राय में), इसलिए यह आवश्यक नहीं है।

इस तरह से विचार करने के बाद, हम पाते हैं कि YAGNI और SOLID वास्तव में ठोस, तुरंत-प्रासंगिक सलाह का एक सामान्य टुकड़ा प्रदान करते हैं: यह संभव नहीं है कि एक सामान्य जेनेरिक रिपॉजिटरी इंटरफ़ेस बनाया जाए।

यह सब सावधानीपूर्वक किया गया अध्ययन सीखने के रूप में बेहद उपयोगी है। जैसा कि आप सीखते हैं, यह समय लेने वाला है, लेकिन समय के साथ आप अंतर्ज्ञान विकसित करते हैं और बहुत जल्दी बन जाते हैं। आपको करने के लिए सही बात पता होगी, लेकिन इन सभी शब्दों को सोचने की ज़रूरत नहीं है जब तक कि कोई आपको यह बताने के लिए क्यों न कहे।


मुझे लगता है कि इस पृष्ठ की अधिकांश चर्चा 2 बड़े दावेदारों को "कम युग्मन" और GRASPrinciples के "उच्च सामंजस्य" को छोड़ देती है। महंगा डिजाइन निर्णय "कम युग्मन" सिद्धांत से उपजा है। जैसे कम युग्मन के लिए SRP + ISP + DIP को कब "एक्टिवेट" करना है। उदाहरण: MVC पैटर्न में एक वर्ग -> 3 कक्षाएं। या इससे भी अधिक महंगा: .dll / .so मॉड्यूल / असेंबली में विभाजित करें। निर्माण के निहितार्थ, प्रोजेक्ट्स, मेकेलिस्ट्स, बिल्ड सर्वर, सोर्स-
वर्स्ड

6

आप मानते हैं कि 'अच्छा डिज़ाइन' का अर्थ है कुछ प्रकार के विचार-विज्ञान और नियमों के औपचारिक सेट, जिन्हें हमेशा बेकार होने पर भी लागू किया जाना चाहिए।

IMO कि ख़राब डिज़ाइन है। YAGNI अच्छी डिज़ाइन का एक घटक है, कभी भी इसके विपरीत नहीं है।


2

आपके उदाहरण में, मैं कहूंगा कि YAGNI प्रबल होना चाहिए। यदि आपको बाद में इंटरफेस जोड़ने की आवश्यकता है तो यह आपको अधिक खर्च नहीं करेगा। वैसे, क्या क्लास द्वारा एक इंटरफ़ेस रखना वास्तव में अच्छा डिज़ाइन है यदि यह बिना किसी लक्ष्य के कार्य करता है?

एक और विचार, शायद कभी-कभी आपको जिस चीज़ की ज़रूरत होती है वह है अच्छा डिज़ाइन नहीं बल्कि पर्याप्त डिज़ाइन। यहाँ विषय पर पदों का बहुत दिलचस्प क्रम दिया गया है:


आपके पहले और तीसरे लिंक एक ही स्थान पर जाते हैं।
डेविड थोरले

2

कुछ लोग तर्क देते हैं, कि इंटरफ़ेस के नाम I. से शुरू नहीं होने चाहिए। विशेष रूप से एक कारण यह है, कि आप वास्तव में इस बात पर निर्भरता को लीक कर रहे हैं कि दिए गए प्रकार एक वर्ग है या एक इंटरफ़ेस।

क्या आपको CustomerFactoryपहली बार में एक वर्ग होने और बाद में इसे एक इंटरफ़ेस में बदलने से रोकता है , जिसे या तो लागू किया जाएगा DefaultCustormerFactoryया UberMegaHappyCustomerPowerFactory3000? केवल एक चीज जिसे आपको बदलना चाहिए, वह स्थान है, जहां कार्यान्वयन तुरंत हो जाता है। और अगर आपके पास अधिक कम अच्छा डिज़ाइन है, तो यह अधिकांश स्थानों पर मुट्ठी भर है।

रिफैक्टरिंग विकास का एक हिस्सा है। बेहतर में थोड़ा कोड होता है, जो कि रिफ्लैक्टर के लिए आसान होता है, एक इंटरफ़ेस और हर एक वर्ग के लिए घोषित एक वर्ग की तुलना में, आपको एक ही समय में कम से कम दो स्थानों पर प्रत्येक विधि का नाम बदलने के लिए मजबूर करता है।

इंटरफेस का उपयोग करने में वास्तविक बिंदु मॉड्यूलरिटी प्राप्त कर रहा है, जो संभवतः अच्छे डिजाइन का सबसे महत्वपूर्ण स्तंभ है। हालांकि, ध्यान दें कि एक मॉड्यूल न केवल बाहरी दुनिया से इसकी डिकॉउलिंग द्वारा परिभाषित किया गया है (भले ही हम इसे बाहरी दृष्टिकोण से कैसे महसूस करते हैं), लेकिन समान रूप से इसके आंतरिक कामकाज द्वारा।
मेरे कहने का मतलब यह है कि चीजों को डिकूप करना, जो स्वाभाविक रूप से एक साथ हैं, इससे कोई मतलब नहीं है। एक तरह से यह प्रति कप व्यक्तिगत शेल्फ के साथ एक अलमारी होने जैसा है।

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

लक्ष्य किसी भी तरह एक एकल भंडार और एक कारखाने के साथ एक स्थानीय समस्या को हल करना नहीं है। लक्ष्य यह है, कि इस निर्णय का आपके बाकी एप्लिकेशन पर कोई प्रभाव नहीं पड़ता है। इस बारे में क्या है।
आप चाहते हैं कि आपके सहकर्मी आपके मॉड्यूल को देखें, एक मुट्ठी भर आत्म-व्याख्यात्मक कॉल देखें और आत्मविश्वास महसूस करें, कि वे सभी संभावित परिष्कृत आंतरिक प्लंबिंग के बारे में चिंता किए बिना उनका उपयोग कर सकते हैं।


0

आप interfaceभविष्य में एक प्रत्याशित एकाधिक कार्यान्वयन बना रहे हैं। आपके पास I<class>अपने कोडबेस में हर वर्ग के लिए भी हो सकता है । मत करो।

बस YAGNI के अनुसार एकल ठोस वर्ग का उपयोग करें। यदि आपको लगता है कि आपको परीक्षण उद्देश्यों के लिए "मॉक" ऑब्जेक्ट की आवश्यकता है, तो मूल कक्षा को दो कार्यान्वयनों के साथ एक सार वर्ग में बदल दें , एक मूल ठोस वर्ग के साथ और दूसरा मॉक कार्यान्वयन के साथ।

आपको स्पष्ट रूप से नए ठोस वर्ग को तत्काल बनाने के लिए मूल वर्ग के सभी इंस्टेंटेशन को अपडेट करना होगा। आप एक स्थिर कंस्ट्रक्टर अप फ्रंट का उपयोग करके इसे प्राप्त कर सकते हैं।

YAGNI का कहना है कि कोड लिखने से पहले उसे लिखने की ज़रूरत नहीं है।

अच्छा डिजाइन अमूर्तता का उपयोग करने के लिए कहता है।

आपके पास दोनों हो सकते हैं। एक वर्ग एक अमूर्त है।


0

क्यों मार्कर इंटरफेस? यह मुझे बताता है कि यह "टैगिंग" से ज्यादा कुछ नहीं कर रहा है। हर कारखाने-प्रकार के लिए एक अलग "टैग" के साथ, क्या बात है?

एक अंतरफलक का उद्देश्य एक वर्ग को "व्यवहार की तरह" कार्य देना है, ताकि उन्हें बोलने के लिए "रिपॉजिटरी-क्षमता" दे सके। इसलिए यदि आपके सभी ठोस रिपॉजिटरी-प्रकार एक ही IRepository की तरह व्यवहार करते हैं (वे सभी IRepository को लागू करते हैं) तो वे सभी अन्य कोड द्वारा उसी तरह से हैंडल किए जा सकते हैं - ठीक उसी कोड द्वारा। इस बिंदु पर आपका डिज़ाइन एक्स्टेंसिबल है। अधिक ठोस रिपॉजिटरी-प्रकारों को जोड़ना, सभी को सामान्य IRepository (ies) के रूप में संभाला जाता है - एक ही कोड सभी सामान्य प्रकारों को "जेनेरिक" रिपॉजिटरी के रूप में संभालता है।

रुकावटें सामान्‍यताओं पर आधारित चीजों को संभालने के लिए होती हैं। लेकिन कस्टम मार्कर इंटरफेस ए) कोई व्यवहार नहीं जोड़ता है। और बी) आपको उनकी विशिष्टता को संभालने के लिए मजबूर करता है।

जब तक आप उपयोगी इंटरफेस डिज़ाइन करते हैं, तब तक आपको विशेष वर्गों, प्रकारों, या कस्टम मार्कर इंटरफेस को संभालने के लिए विशेष कोड लिखने के लिए OO अच्छाई नहीं मिलती है, जिसमें कंक्रीट कक्षाओं के लिए 1: 1 सहसंबंध होता है। यह निरर्थक अतिरेक है।

हाथ से मैं एक मार्कर इंटरफ़ेस देख सकता हूं यदि, उदाहरण के लिए, आपको बहुत सारे विभिन्न वर्गों के एक दृढ़ता से टाइप किए गए संग्रह की आवश्यकता थी। संग्रह में वे सभी "ImarkerInterface" हैं, लेकिन जैसा कि आप उन्हें बाहर खींचते हैं, आप उन्हें उनके उचित प्रकारों के लिए डाल रहे हैं।


0

क्या आप अभी, एक उचित उचित ICustomerRepository लिख सकते हैं? उदाहरण के लिए, (वास्तव में यहां तक ​​पहुंचना, शायद एक बुरा उदाहरण है) अतीत में आपके ग्राहकों ने हमेशा पेपल का उपयोग किया है? या कंपनी में हर कोई अलीबाबा के साथ हुक करने के बारे में चिंतित है? यदि हां, तो आप अब और अधिक जटिल डिजाइन का उपयोग करना चाहते हैं, और अपने मालिकों को दूरदर्शी दिखाई दे सकते हैं। :-)

नहीं तो रुको। एक इंटरफ़ेस पर अनुमान लगाने से पहले एक या दो वास्तविक कार्यान्वयन आमतौर पर विफल होते हैं। दूसरे शब्दों में, जब तक आप सामान्यीकरण करने के लिए कुछ उदाहरण नहीं देते हैं, तब तक एक सामान्य डिज़ाइन पैटर्न का सामान्यीकरण / सार / उपयोग न करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.