2012-03-09 12 views
7

प्रश्न"बताओ, नहीं पूछें" एकाधिक डोमेन से अधिक वस्तुओं

जब एक से अधिक ऑब्जेक्ट को शामिल एक समारोह प्रदर्शन कर मैं कैसे "Tell, Don't Ask" सिद्धांत का पालन करते हैं।

उदाहरण - एक रिपोर्ट

मैं निम्नलिखित वस्तुओं (उदाहरण के उद्देश्यों केवल) है जनरेट कर रहा है:

कार हार्स, खरगोश

इन वस्तुओं के बीच कोई रिश्ता नहीं है, , लेकिन मैं इन वस्तुओं के आधार पर एक रिपोर्ट उत्पन्न करना चाहता हूं:

createHtmlReport(Car car, Horse horse, Rabbit rabbit){ 
    Report report = new Report() 

    report.setSomeField(car.getSerialNumber()) 
    report.setAnotherField(horse.getNumberOfLegs()) 
    // ...etc  
} 

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

car.createHtmlReport() 
horse.createHtmlReport() 
rabbit.createHtmlReport() 

... लेकिन फिर मैं 3 आंशिक रिपोर्ट प्राप्त करें। इसके अलावा, मुझे नहीं लगता कि एक खरगोश को यह जानना चाहिए कि मुझे हर एक रिपोर्ट को कैसे उत्पन्न करना है (एचटीएमएल, जेएमएस, एक्सएमएल, जेएसओएन ....)।

अंत में, जबकि रिपोर्ट मैं कई वस्तुओं पर स्विच कर सकते हैं पैदा:

if (car.getWheels() == 4 || horse.getLegs() == 4) 
    // do something 
+0

लिंक और प्रश्न के लिए +1 और एफएवी। – knownasilya

उत्तर

8

रिपोर्ट अपने स्वयं बनाने की क्षमता बनाए रखना चाहिए।

इस मामले में, प्रत्येक IReportable ऑब्जेक्ट को void UpdateReport(Report aReport) लागू करना चाहिए।

जब Report.CreateReport(List<Reportable> aList) शुरू हो जाती है, यह सूची के माध्यम से iterates और UpdateReport के अपने स्वयं के कार्यान्वयन में प्रत्येक वस्तु का आह्वान:

aReport.AddCar(serialNumber) 
aReport.AddHorse(horseName) 

CreateReport के अंत में, रिपोर्ट वस्तु का अपना परिणाम उपज चाहिए।

+1

आगंतुक और डबल प्रेषण नियम! –

+0

स्पष्ट होने के लिए, 'रिपोर्ट' में' AddCar' और 'AddHorse' लागू होना चाहिए? मुझे लगता है कि इन विधि नामों को उदाहरण के लिए लिया जाता है, लेकिन वे बहुत भ्रामक हैं और। असल में, मुझे यह समझने के लिए 10 मिनट की तरह बर्बाद कर दिया गया कि इन विधियों के पास कार और घोड़े के प्रकार के साथ कुछ भी नहीं है o_O –

6

"बताओ मत पूछें" नियम का लक्ष्य उन परिस्थितियों की पहचान करने में मदद करना है जहां दी गई वस्तु के साथ झूठ बोलने की ज़िम्मेदारी समाप्त हो जाती है (बुरी चीज)।
हम आपके मामले में क्या जिम्मेदारियां देख सकते हैं? क्या मैं देख रहा हूँ है:

1) जानते हुए भी कैसे (रिपोर्ट स्वरूपित करने के लिए एक्सएमएल, ASCII, एचटीएमएल, आदि)
2) में जानते हुए भी क्या हो जाता है जो रिपोर्ट

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

1

मैं बिल्कुल इस पद्धति का नाम (आगंतुक, बिल्डर, ...) पता नहीं है:

public interface HorseView { 
    void showNumberOfLegs(int number); 
} 

public interface CarView { 
    void showNumberOfWheels(int number); 
    void showSerialNumber(String serialNumber); 
} 

public class Horse { 

    void show(HorseView view) { 
     view.showNumberOfLegs(this.numberOfLegs); 
    } 

} 

public class Car { 

    void show(CarView view) { 
     view.showNumberOfWheels(this.numberOfWheels); 
     view.showSerialNumber(this.serialNumber); 
    } 

} 

public class HtmlReport implements HorseView, CarView { 

    public void showNumberOfLegs(int number) { 
     ... 
    } 

    public void showNumberOfWheels(int number) { 
     ... 
    } 

    public void showSerialNumber(String serialNumber) { 
     ... 
    } 

} 

public XmlModel implements HorseView, CarView { 
    ... 
} 

public JsonModel implements HorseView, CarView { 
    ... 
} 

इस तरह से आप एक ही डोमेन वस्तु का अधिक प्रतिनिधित्व हो सकता है, नहीं का उल्लंघन "नहीं है बताओ "सिद्धांत पूछो।

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

  • कोई संबंधित समस्या नहीं^_^