2010-05-24 22 views
26

के साथ बहुत बड़ी वस्तुओं से बचने के लिए कैसे हम एक बड़ी वेबसाइट के कार्यान्वयन के लिए डोमेन संचालित डिजाइन का पालन कर रहे हैं।डोमेन संचालित डिजाइन

हालांकि डोमेन ऑब्जेक्ट्स पर व्यवहार डालने से हम कुछ बहुत बड़ी कक्षाओं के साथ समाप्त हो रहे हैं।

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

मैं बच्चे की बहुत सारी में लाने से बचें करने के लिए उत्सुक हूँ वस्तुओं उदा user.getOrderHistory()। getLatestOrder()।

इस समस्या से बचने के लिए अन्य रणनीतियां क्या उपयोग की जा सकती हैं?

उत्तर

2

मैं एक ही समस्या में पड़ गए, और मैंने पाया है कि बच्चे को "प्रबंधक" वस्तुओं का उपयोग कर हमारे मामले में सबसे अच्छा समाधान था।

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

User u = ...; 
OrderHistoryManager histMan = user.getOrderHistoryManager(); 

तो फिर तुम कुछ भी आप चाहते हैं के लिए histMan उपयोग कर सकते हैं। जाहिर है आपने इस बारे में सोचा, लेकिन मुझे नहीं पता कि आप इससे क्यों बचना चाहते हैं। यह आपकी चिंताओं को अलग करता है जब आपके पास ऐसी वस्तुएं होती हैं जो बहुत अधिक होती हैं।

इस बारे में सोचें। यदि आपके पास "मानव" वस्तु थी, और आपको chew() विधि लागू करना था। क्या आप इसे Human ऑब्जेक्ट या Mouth बच्चे ऑब्जेक्ट पर रखेंगे।

19

मुद्दों आप देख रहे हैं द्वारा डोमेन प्रेरित डिजाइन की वजह से नहीं कर रहे हैं, बल्कि चिंताओं की जुदाई की कमी से। डोमेन संचालित डिजाइन सिर्फ डेटा और व्यवहार को एक साथ रखने के बारे में नहीं है।

पहली बात मैं सिफारिश करेंगे एक दिन का समय ले रही है और Domain Driven Design Quickly जानकारी क्यू से एक मुफ्त डाउनलोड के रूप में उपलब्ध पढ़ रहा है। यह विभिन्न प्रकार के डोमेन ऑब्जेक्ट्स का एक सिंहावलोकन प्रदान करेगा: संस्थाएं, मूल्य वस्तुएं, सेवाएं, भंडार, और कारखानों।

दूसरी बात मैं सिफारिश करेंगे Single Responsibility Principle को पढ़ने जाने के लिए है।

तीसरे बात मैं सुझाव है कि आप Test Driven Development में अपने आप को विसर्जित करने के लिए शुरू होता है। परीक्षणों को लिखकर डिजाइन करना सीखने के दौरान पहले आपको बहुत अच्छा डिजाइन नहीं करना पड़ेगा, वे आपको कमजोर युग्मित डिजाइनों की दिशा में मार्गदर्शन करते हैं और पहले डिजाइन मुद्दों को प्रकट करते हैं।

आपके द्वारा प्रदान किए गए उदाहरण में, वेबसाइट यूज़र के पास निश्चित रूप से बहुत अधिक जिम्मेदारियां हैं। वास्तव में, आपको WebsiteUser की आवश्यकता नहीं हो सकती है क्योंकि उपयोगकर्ताओं को आम तौर पर ISecurityPrincipal द्वारा दर्शाया जाता है।

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

दीर्घकालिक, आपको वास्तव में एरिक इवांस द्वारा Domain Driven Design पुस्तक लेनी चाहिए। यह एक बड़ा पढ़ा है, लेकिन आपके समय के लायक है। मैं आपको अपनी भाषा वरीयता के आधार पर Agile Software Development, Principles, Patterns, and Practices या Agile Principles, Patterns, and Practices in C# चुनने की सलाह भी दूंगा।

+0

इस टिप्पणी के लिए धन्यवाद। मैंने श्री इवांस की किताब पढ़ी है। मुझे लगता है कि समस्या तब होती है जब एक इकाई के कई सहयोगी होते हैं। जैसे एक वेबसाइट यूज़र (या प्रिंसिपल) में नवीनतम ऑर्डर, पहला ऑर्डर, एक शॉपिंग कार्ट, पासवर्ड इत्यादि है। ये सभी सीधे वेबसाइट उपयोगकर्ता से संबंधित हैं। – Pablojim

+1

प्रमाणीकरण, लंबित आदेश स्थिति (यानी शॉपिंग कार्ट), और ऑर्डर इतिहास वास्तव में अलग-अलग चिंताएं हैं। किसी दिए गए उपयोगकर्ता के लिए ऑर्डर इतिहास पुनर्प्राप्त करने के व्यवहार को समाहित करने के लिए IArhenticationService में प्रमाणीकरण को खींचने और IOrderHistoryRepository (या शायद एक IOrderHistoryService) बनाने पर विचार करें। –

2

अंगूठे का पालन करने का एक बहुत ही सरल नियम है "आपकी कक्षा में अधिकांश विधियों में आपकी कक्षा में अधिकांश इंस्टेंस चर का उपयोग करना है" - यदि आप इस नियम का पालन करते हैं तो कक्षाएं स्वचालित रूप से सही आकार के होंगी।

+0

यह एक दिलचस्प अवलोकन है। क्या आप कोई लिंक प्रदान कर सकते हैं? – ya23

+0

एसआरपी को याद रखने के लिए यह मूल रूप से एक आसान तरीका है - मैंने इसे ओओ किताबों में से एक में पढ़ा लेकिन इसे वास्तव में दिलचस्प पाया और यह मेरे दिमाग में फंस गया। – OpenSource

+0

इसे उच्च समेकन – beluchin

2

आप कुछ चीजों को उलझाने पर विचार करना चाह सकते हैं। उदाहरण के लिए, किसी ग्राहक को ऑर्डर प्रॉपर्टी (या ऑर्डर का इतिहास) रखने की आवश्यकता नहीं होती है - आप उन्हें ग्राहक वर्ग से बाहर छोड़ सकते हैं। तो

 
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) { 
    List = customer.getOrders(from, to); 
    for (Order order : orders) { 
     order.doSomething(); 
    } 
} 

के बजाय आप के बजाय कर सकता है:

 
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) { 
    List = orderService.getOrders(customer, from, to); 
    for (Order order : orders) { 
     order.doSomething(); 
    } 
} 

यह 'हारने' युग्मन है, लेकिन अभी भी आप सभी एक ग्राहक से संबंधित आदेश प्राप्त कर सकते हैं। मुझे यकीन है कि मेरे से बेहतर लोग हैं जिनके पास उपरोक्त संदर्भ देने वाले सही नाम और लिंक हैं।

9

हालांकि वास्तविक मनुष्यों की बहुत सारी ज़िम्मेदारियां हैं, आप God object anti-pattern की तरफ बढ़ रहे हैं।

के रूप में दूसरों को संकेत दिया है, तो आप अलग डेटा संग्रह स्थान और/या डोमेन सेवा में उन जिम्मेदारियों को निकालने चाहिए। उदा .:

SecurityService.Authenticate(credentials, customer) 
OrderRepository.GetOrderHistoryFor(Customer) 
RefundsService.StartRefundProcess(order) 

नामकरण परंपराओं के साथ विशिष्ट (अर्थात OrderManager के बजाय, का उपयोग OrderRepository या OrderService)

आप इस समस्या हुई वजह से सुविधा। यानी WebsiteUser को कुल रूट के रूप में और इसके माध्यम से सब कुछ एक्सेस करने के लिए सुविधाजनक है।

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

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

आशा है कि मदद करता है!

1

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

+0

+1 के रूप में भी जाना जाता है यह डीसीआई के साथ डीडीडी की तरह दिखने के करीब है। सिस्टम क्या करता है उससे सिस्टम अलग है। – Gordon

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