2010-03-11 7 views
5

इस मंच पर पढ़ने के कुछ हफ्तों बाद मैंने सोचा कि यह मेरे लिए पहली पोस्ट करने का समय था।कोड पूर्ण 2, रचना और प्रतिनिधिमंडल

मैं वर्तमान में कोड पूर्ण को फिर से पढ़ रहा हूं। मुझे लगता है कि यह आखिरी बार 15 साल है, और मुझे लगता है कि मैं अभी भी कोड नहीं लिख सकता ;-)

वैसे भी कोड 138 पर कोड पूर्ण होने पर आपको यह कोडिंग डरावनी उदाहरण मिल जाता है। (मैंने कुछ कोड हटा दिए हैं)

class Emplyee { 
public: 
FullName GetName() const; 
Address GetAddress() const; 
PhoneNumber GetWorkPhone() const; 
... 

bool IsZipCodeValid(Address address); 
... 

private: 
    ... 
} 

स्टीव सोचता है कि बुरा क्या है कि कार्य कम से कम संबंधित हैं। या उसने लिखा है "कर्मचारियों और दिनचर्या के बीच कोई तार्किक संबंध नहीं है जो ज़िप कोड, फोन नंबर या नौकरी वर्गीकरण की जांच करते हैं"

ठीक है, मैं पूरी तरह से उससे सहमत हूं। शायद नीचे दिए गए उदाहरण की तरह कुछ बेहतर है।

class ZipCode 
{ 
public: 
bool IsValid() const; 
    ... 
} 

class Address { 
public: 
    ZipCode GetZipCode() const; 
    ... 
} 

class Employee { 
public: 
Address GetAddress() const; 
    ... 
} 

यह जांचते समय कि ज़िप मान्य है या नहीं, आपको ऐसा कुछ करने की आवश्यकता होगी।

employee.GetAddress().GetZipCode().IsValid(); 

और यह Law of Demeter से संबंधित नहीं है।

तो यदि आप तीनों बिंदुओं में से दो को हटाना चाहते हैं, तो आपको इस तरह प्रतिनिधिमंडल और कुछ रैपर कार्यों का उपयोग करने की आवश्यकता है।

class ZipCode 
{ 
public: 
bool IsValid(); 
} 

class Address { 
public: 
    ZipCode GetZipCode() const; 
    bool IsZipCodeValid() {return GetZipCode()->IsValid()); 
} 

class Employee { 
public: 
FullName GetName() const; 
Address GetAddress() const; 
bool IsZipCodeValid() {return GetAddress()->IsZipCodeValid()); 
PhoneNumber GetWorkPhone() const; 
} 

employee.IsZipCodeValid(); 

लेकिन फिर आपके पास दिनचर्या है जिसमें कोई तार्किक कनेक्शन नहीं है।

मुझे व्यक्तिगत रूप से लगता है कि इस पोस्ट में सभी तीन उदाहरण खराब हैं। क्या यह कोई और तरीका है जिसके बारे में मैंने सोचा नहीं है?

+0

मुझे पता है कि बहुत सारे प्रोग्रामर कोड को पूरा करते हैं, लेकिन ईमानदारी से मैंने कभी नहीं किया। यह एक बहुत उबाऊ पढ़ा था। – JonH

+0

यह उस पर निर्भर करता है जब आप इसे पढ़ते हैं। यदि आप जूनियर डेवलपर हैं तो यह एक अच्छा पढ़ा है।यदि आप एक अनुभवी डेवलपर हैं तो मुझे लगता है कि पुस्तक में लिखी गई चीजें सिर्फ असाधारण होने के बिना समझ में आती हैं। –

+1

@ जोनएच मैं सहमत हूं - उनकी सर्वश्रेष्ठ पुस्तक वास्तव में "रैपिड डेवलपमेंट" है, जो कुछ लोगों ने पढ़ा है - यह बहुत अच्छा है। –

उत्तर

1

बाद में यह बनाम भुगतान अब भुगतान है।

आप प्रतिनिधिमंडल और रैपर कार्यों को आगे बढ़ा सकते हैं (अब भुगतान करें) और उसके बाद कर्मचारी के अंदरूनी हिस्सों को बदलने में कम काम है। IZZCodeValid() बाद में। या, आप

employee.GetAddress().GetZipCode().IsValid();
लिखकर IsZipCodeValid के माध्यम से सुरंग कर सकते हैं, जहां भी आपको कोड में इसकी आवश्यकता है, लेकिन बाद में भुगतान करना चाहिए कि आप इस श्रेणी को तोड़ने के तरीके में अपनी कक्षा डिज़ाइन को बदलने का निर्णय लेना चाहिए।

आपको अपना जहर चुनना है। ;)

+0

यह शायद सबसे अच्छा जवाब है। क्योंकि वे समस्या का कोई सुरुचिपूर्ण समाधान नहीं है। – Arlukin

7

आप तार्किक कनेक्शन याद कर रहे हैं:

class ZipCode 
{ 
public: 
bool IsValid(); 
} 

class Address { 
public: 
    ZipCode GetZipCode() const; 
    bool IsAddressValid(); 
    bool IsValid() {return GetZipCode()->IsValid() && IsAddressValid()); 
} 

class Employee { 
public: 
FullName GetName() const; 
Address GetAddress() const; 
bool IsEmployeeValid(); 
bool IsValid() {return GetAddress()->IseValid() && IsEmployeeValid()); 
PhoneNumber GetWorkPhone() const; 
} 

employee.IsValid(); 
+0

आपको अभी भी 'ZipCode :: IsValid()' में अंततः ड्रिल करने की आवश्यकता होगी। आप 'कर्मचारी को कहते हैं। यह वैध()' और यह झूठा लौटाता है। ठीक है, कर्मचारी वैध क्यों नहीं है? तो आप 'कर्मचारी को कॉल करें। GetAddress()। IsValid()', और यह झूठी वापसी करता है। ठीक है, पता मान्य क्यों नहीं है? तो आप 'कर्मचारी को कॉल करें। GetAddress()। GetZipCode()। IsValid()' और आप मूल समस्या पर वापस आ गए हैं। – indiv

+0

प्लस कि आप एक संवाद बॉक्स या वेबपृष्ठ में आउटपुट के लिए, ZipCode पर GetValue() को कॉल करना चाहते हैं। यह आपको एक ही समस्या देगा। – Arlukin

+0

@indiv, यदि आप इस उदाहरण को फेस वैल्यू पर ले जा रहे हैं तो हाँ आपको उस तरीके से ड्रिल करना होगा, लेकिन आपके पास शायद एक विधि होगी जो आपके लिए यह करेगी और डेटा के लिए त्रुटि डेटा/संदेश वापस प्रस्तुत करेगी प्रवेश स्क्रीन यदि यह अमान्य स्थिति ऐप में खराब डेटा का परिणाम है तो मुझे लगता है कि जवाब आपके मॉडल में इंजेक्शन देने से पहले डेटा को साफ करना है। – Lazarus

0

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

class Address 
{ 
    public: 
     static IsZipValid(ZipCode zip) { return zip.isValid(); } 
}; 

तो फिर तुम

Address::IsZipValid(employee.GetAddress().GetZipCode()); 

मुझे लगता है कि यह तार्किक सहयोग और Demeter के कानून के अपने सीमा के अन्दर संतोषजनक है।

+0

लेकिन क्या आप वास्तव में इसके साथ कुछ भी जीतते हैं? शायद व्यक्तिगत स्वाद का सवाल है, लेकिन मुझे लगता है कि अधिक बिंदु पढ़ने के लिए आसान है। पता :: IsZipValid (कर्मचारी। GetAddress()। GetZipCode()); बनाम कर्मचारी। गेट एड्रेस()। GetZipCode()। IsZipValid(); – Arlukin

+0

@ आर्लुकिन: नहीं, मुझे विश्वास नहीं है कि आप कुछ हासिल करते हैं। मैं बस सवाल के जवाब में जवाब दे रहा था। डेमेटर मुझ पर कोई कानून नहीं लगाता है, इसलिए मैं इसे कर्मचारी के रूप में लागू कर दूंगा। GetAddress()। GetZipCode.IsZipValid()। इस तरह मेरे लिए प्राकृतिक लगता है। – indiv

+0

@ आर्लुकिन, यह जीतने या हारने के बारे में नहीं है, यह एक मॉडल बनाने के बारे में है जो समझ में आता है। यदि, दिन के अंत में, एक तरफ आपके लिए एक और तरीका अधिक प्राकृतिक लगता है और आप एक टीम का हिस्सा नहीं हैं (यदि आप टीम मार्गदर्शन प्राप्त कर रहे हैं) तो जो भी आपको समझ में आता है उसके साथ जाएं। मुझे यकीन है कि अगर आपको एक कमरे में दो प्रोग्रामर मिलते हैं तो आपको एक निश्चित समाधान को कोड करने के तरीके पर छह राय मिलेंगी;) – Lazarus

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