2008-10-04 15 views
24

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

कोड कि SRP के पक्ष में है लेकिन बताओ पूछो मत का उल्लंघन करती है:

Customer bob = ...; 
// TransferObjectFactory has to use Customer's accessors to do its work, 
// violates Tell Don't Ask 
CustomerDTO dto = TransferObjectFactory.createFrom(bob); 

कोड को बताएँ पूछो मत करो/जानकारी विशेषज्ञ के पक्ष में है लेकिन SRP का उल्लंघन करती है कि यहाँ मैं किस बारे में बात कर रहा हूँ है:

Customer bob = ...; 
// Now Customer is doing more than just representing the domain concept of Customer, 
// violates SRP 
CustomerDTO dto = bob.toDTO(); 

यदि वे वास्तव में बाधाओं में हैं, तो यह मेरे ओसीडी का एक निष्ठा है। अन्यथा, कृपया मुझे इस बात पर भरें कि ये अभ्यास शांतिपूर्वक कैसे सह-अस्तित्व में हो सकते हैं। धन्यवाद।

संपादित करें: कोई चाहता है पदों की एक परिभाषा -

सूचना विशेषज्ञ: वस्तुओं डेटा संचालन के लिए आवश्यक आपरेशन

की मेजबानी करनी चाहिए कि बताओ पूछो मत करो: के लिए वस्तुओं मत पूछो काम करने के लिए डेटा; प्रत्येक वस्तु एक संक्षिप्त रूप से परिभाषित जिम्मेदारी

+0

आपके द्वारा उपयोग की जा रही शर्तों की एक छोटी प्रस्तुति सहायक हो सकती है। – shoosh

+3

संक्षिप्त उत्तर हाँ है ... लंबा यह है कि कभी-कभी लोग (अकादमिक) अपने सिर को अपने गधे तक फंस जाते हैं, वे भूल जाते हैं कि प्रोग्रामिंग अभी तक एक परिपूर्ण विज्ञान नहीं है, .. हमारे पास ऐसी भाषा नहीं है इन सभी सिद्धांतों को पूरा करने के लिए पर्याप्त साफ करें। सिद्धांत को तोड़ो जो इसे सबसे ज्यादा समझ में आता है। – Stimul8d

+1

आपका दूसरा उदाहरण एसआरपी का उल्लंघन करता है, लेकिन वास्तव में टेल डॉट न पूछने का एक अच्छा उदाहरण नहीं है। – koenmetsu

उत्तर

8

मुझे नहीं लगता कि यह है कि वे अंतर पर इतना कर रहे हैं के रूप में वे अलग अलग चीजें हैं जो आप दर्द का कारण होगा पर बल कर रहे हैं होना चाहिए: काम

एकल जिम्मेदारी सिद्धांत करने के लिए वस्तुओं बता । एक यह कोड बनाने के बारे में है कि यह स्पष्ट करने के लिए कि जहां विशेष जिम्मेदारियां हैं और युग्मन को कम करना है, दूसरा वर्ग को संशोधित करने के कारणों को कम करने के बारे में है।

हम सभी को कोड बनाने और किस निर्भरता को डिजाइन में पेश करने के लिए तैयार हैं, इस बारे में हर दिन निर्णय लेना पड़ता है।

हमने कई उपयोगी दिशानिर्देश, अधिकतम और पैटर्न बनाए हैं जो निर्णय लेने में हमारी सहायता कर सकते हैं।

इनमें से प्रत्येक हमारे डिजाइन में मौजूद विभिन्न प्रकार की समस्याओं का पता लगाने के लिए उपयोगी है। किसी भी विशिष्ट समस्या के लिए जो आप देख रहे हैं वहां कहीं भी एक मीठी जगह होगी।

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

उस विशिष्ट समस्या के लिए जो आप आज देख रहे हैं, आपको यह तय करने की आवश्यकता है कि आपको दर्द का कारण होने वाले सबसे महत्वपूर्ण कारक क्या हैं।

+0

इसलिए, कुछ मामलों में कम से कम _all_ SOLID सिद्धांत एक साथ संतुष्ट नहीं हो सकते हैं - यानी नुकसान हो सकता है और "उनमें से अधिक बेहतर" मेट्रिक्स नहीं हैं :) – mlvljr

+6

हां वास्तव में। यही कारण है कि प्रोग्रामिंग एक कला है और नियमों का अंधा आवेदन नहीं है। – DJClayworth

2

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

दूसरी ओर .toDTO विधि संदिग्ध है - ग्राहक को यह ज़िम्मेदारी क्यों चाहिए? "शुद्धता" के लिए मेरे पास एक और वर्ग होगा जो नौकरी का काम करता है, यह ग्राहक जैसी व्यावसायिक वस्तुओं से डीटीओ बनाना था।

इन सिद्धांतों को मत भूलना सिद्धांत हैं, और जब आप बदलते आवश्यकताओं को हल करने तक सरल समाधान के साथ दूर कर सकते हैं, तो ऐसा करें। अनावश्यक जटिलता निश्चित रूप से बचने के लिए कुछ है।

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

5

जब आप कुछ करने के लिए ऑब्जेक्ट बताने के लिए ऑब्जेक्ट की स्थिति मांगते हैं तो आप "बताओ मत पूछें" के बारे में बात कर सकते हैं।

आपके पहले उदाहरण में TransObjectFactory.create केवल एक कनवर्टर से। यह ग्राहक की स्थिति का निरीक्षण करने के बाद कुछ करने के लिए ग्राहक वस्तु को नहीं बताता है।

मुझे लगता है कि पहला उदाहरण सही है।

0

मैं प्रतिनिधि के रूप में आपके दो उदाहरणों से 100% सहमत नहीं हूं, लेकिन एक सामान्य परिप्रेक्ष्य से आप दो वस्तुओं और केवल दो वस्तुओं की धारणा से तर्क कर रहे हैं।

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

यह एक रचना समाधान है जो किसी अन्य प्रकार के नियंत्रक पर निर्भर करता है ताकि अन्य वस्तुओं के बीच समन्वय और प्रतिनिधि को आंतरिक विवरण में फेंक दिया जा सके।

1

बहन वर्ग (जैसे आपके पास) के साथ डीटीओ आपके द्वारा बताए गए सभी तीन सिद्धांतों का उल्लंघन करते हैं, और encapsulation, यही कारण है कि आपको यहां समस्याएं हैं।

आप इस ग्राहक डीटीओ का उपयोग किसके लिए कर रहे हैं, और आप ग्राहक का उपयोग क्यों नहीं कर सकते, और ग्राहक के भीतर डीटीओ डेटा प्राप्त कर सकते हैं? यदि आप सावधान नहीं हैं, तो ग्राहक डीटीओ को ग्राहक की आवश्यकता होगी, और ग्राहक को ग्राहक डीटीओ की आवश्यकता होगी।

टेलडोंटस्क कहते हैं कि यदि आप एक वस्तु (जैसे एक ग्राहक) पर निर्णय ले रहे हैं, तो वह निर्णय ग्राहक वर्ग के अंदर ही किया जाना चाहिए।

एक उदाहरण अगर आप किसी भी बकाया बिलों का भुगतान करने ग्राहक को याद दिलाना चाहते है, तो आप फोन

List<Bill> bills = Customer.GetOutstandingBills(); 
    PaymentReminder.RemindCustomer(customer, bills); 

इस उल्लंघन है। इसके बजाय आप

Customer.RemindAboutOutstandingBills() 

(और निश्चित रूप से आप ग्राहक के निर्माण पर एक निर्भरता के रूप में PaymentReminder में पारित करने के लिए की आवश्यकता होगी) करना चाहते हैं।

सूचना विशेषज्ञ एक ही बात कहता है।

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

1

क्रैग लारमन इस पर चर्चा की, जब वह यूएमएल और पैटर्न लागू करने के लिए GRASP शुरू की वस्तु उन्मुख विश्लेषण और डिजाइन और Iterative विकास (2004):

कुछ स्थितियों में, एक समाधान विशेषज्ञ ने सुझाव दिया, अवांछनीय है आमतौर पर युग्मन और एकजुटता में समस्याओं की वजह से (इन सिद्धांतों को बाद में इस अध्याय में चर्चा की जाती है)।

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

ये सभी समस्याएं बुनियादी वास्तुकला सिद्धांत का उल्लंघन करती हैं: प्रमुख सिस्टम चिंताओं को अलग करने के लिए डिज़ाइन। एप्लिकेशन लॉजिक को एक ही स्थान पर रखें (जैसे डोमेन सॉफ़्टवेयर ऑब्जेक्ट्स), डेटाबेस लॉजिक को किसी अन्य स्थान पर रखें (जैसे एक अलग दृढ़ता सेवा उपप्रणाली), और इसी तरह, एक ही घटक में विभिन्न सिस्टम चिंताओं को जोड़ने के बजाय। [11]

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

इस प्रकार एसआरपी आम तौर पर सूचना विशेषज्ञ को टंप करता है।

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

CustomerDTO dto = new CustomerDTO(bob); 

आप नए से एलर्जी हो, तो आप स्थिर जा सकते हैं:

CustomerDTO dto = CustomerDTO.buildFor(bob); 

या, यदि आप दोनों से नफरत है, हम वापस एक सार के लिए वापस आते हैं फैक्टरी:

public abstract class DTOFactory<D, E> { 
    public abstract D createDTO(E entity); 
} 


public class CustomerDTOFactory extends DTOFactory<CustomerDTO, Customer> { 
    @Override 
    public CustomerDTO createDTO(Customer entity) { 
     return new CustomerDTO(entity); 
    } 
}