2009-03-07 19 views
15

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

उदाहरण के लिए, वर्तमान में यह है:

$ticket = new SupportTicket(
    $customer, 
    $title, 
    $start_ticket_now, 
    $mail_customer 
); 

जैसे ही वस्तु बनाई गई है, यह एक डेटाबेस में एक पंक्ति डाल देता हूँ, जाने के लिए और ग्राहक मेल एक पुष्टिकरण ई-मेल, संभवतः भेज निकटतम तकनीशियन, आदि के लिए एक पाठ संदेश ..

क्या कोई कन्स्ट्रक्टर उस काम को बंद कर रहा है, या निम्न की तरह कुछ और चाहिए?

$ticket = new SupportTicket($customer, $title); 
$customer->confirmTicketMailed($ticket); 
$helpdesk->alertNewTicket($ticket); 

यदि यह मदद करता है, तो ऑब्जेक्ट्स ActiveRecord शैली पर आधारित हैं।

मुझे लगता है कि यह राय का विषय हो सकता है, लेकिन आपको क्या लगता है कि सबसे अच्छी बात है?

+0

आप इस प्रासंगिक हो सकते हैं:। //www.yegor256: (http [कंस्ट्रक्टर्स कोड-मुक्त होना चाहिए]। कॉम/2015/05/07/ctors-must-be-code-free.html) – yegor256

उत्तर

38

यदि निर्माता सभी काम करता है तो कन्स्ट्रक्टर कई अन्य डोमेन ऑब्जेक्ट्स के बारे में जानता है। यह एक निर्भरता समस्या पैदा करता है। ticket वास्तव में Customer और HelpDesk के बारे में पता होना चाहिए? जब नई सुविधाएं जोड़ दी जाती हैं, तो क्या यह संभव नहीं है कि नए डोमेन ऑब्जेक्ट वर्कफ़्लो में जोड़े जाएंगे, और इसका मतलब यह नहीं है कि हमारे खराब ticket को डोमेन ऑब्जेक्ट्स की बढ़ती आबादी के बारे में जानना होगा?

इस तरह निर्भरता के स्पाइडरवेब्स के साथ समस्या यह है कि किसी भी डोमेन ऑब्जेक्ट में एक स्रोत कोड परिवर्तन हमारे गरीब ticket पर असर डालेगा। ticket में होगा सिस्टम का ज्ञान जो कोई फर्क नहीं पड़ता कि ticket शामिल होगा। आपको उस कन्स्ट्रक्टर के अंदर ग़लत if कथन एकत्रित करना, कॉन्फ़िगरेशन डेटाबेस की जांच करना, और सत्र स्थिति, और कई अन्य चीजें मिलेंगी। ticket ईश्वर वर्ग बनने के लिए बढ़ेगा।

चीजों को करने वाले रचनाकारों को नापसंद करने का एक अन्य कारण यह है कि यह उनके आसपास की वस्तुओं को परीक्षण करने में बहुत मुश्किल बनाता है। मुझे बहुत सारी नकली वस्तुओं को लिखना पसंद है। जब मैं customer के खिलाफ एक परीक्षण लिखता हूं, तो मैं इसे ticket पर एक मॉक आउट करना चाहता हूं। यदि ticket का कन्स्ट्रक्टर वर्कफ़्लो को नियंत्रित करता है, और customer और अन्य डोमेन ऑब्जेक्ट्स के बीच नृत्य करता है, तो यह संभावना नहीं है कि मैं इसे customer का परीक्षण करने के लिए तैयार कर पाऊंगा।

मेरा सुझाव है कि आप The SOLID Principles पढ़ लें, एक पेपर जिसे मैंने ऑब्जेक्ट ओरिएंटेड डिज़ाइन में निर्भरता प्रबंधन के बारे में कई साल पहले लिखा था।

+0

ईश्वर सीधे बात करता है आप, आशीर्वाद महसूस करते हैं। रॉबर्ट सी मार्टिन ने आपका जवाब उत्तर दिया: ओ –

4

चीजों को विभाजित करें। असल में, आप टिकट नहीं जानना चाहते कि उसे ई-मेल आदि कैसे भेजना चाहिए। यह कक्षा जैसी सेवा का काम है।

[अपडेट] मुझे नहीं लगता कि सुझाए गए फैक्ट्री पैटर्न इसके लिए अच्छे हैं। एक कारखाना उपयोगी होता है यदि आप इस तर्क को टिकट में डाले बिना टिकट के विभिन्न कार्यान्वयन बनाना चाहते हैं (उदाहरण के लिए अधिभारित कन्स्ट्रक्टर के माध्यम से)।

डोमेन-संचालित डिज़ाइन में प्रस्तावित सेवा अवधारणा पर नज़र डालें।

सेवाएं: जब कोई ऑपरेशन किसी वस्तु से अवधारणात्मक रूप से संबंधित नहीं होता है। समस्या के प्राकृतिक रूपों के बाद, आप इन परिचालनों को सेवाओं में कार्यान्वित कर सकते हैं। सेवा अवधारणा को GRASP में "शुद्ध फैब्रिकेशन" कहा जाता है।

4

समस्या, एक OO डिजाइन दृष्टिकोण से, इतना है कि कार्यक्षमता एक निर्माता में लागू किया जाना चाहिए कि क्या है (जैसा कि उस वर्ग पर अन्य तरीकों के भीतर के खिलाफ) नहीं है, लेकिन SupportTicket वर्ग कैसे करना है पता होना चाहिए कि क्या उन सभी चीजें।

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

Single Responsibility Principle पर एक नज़र डालें, जो इसे करने के लाभ बताते हैं। विशेष रूप से, this ब्लॉग एसआरपी और अच्छे ओओ डिजाइन के अन्य कीस्टोन सिद्धांतों को पढ़ने के लिए एक अच्छी जगह है।

+0

यह सिर पर कील को हिट करता है। चाहे आप एक कारखाने का उपयोग करें (जैसा कि अन्य पदों का उल्लेख है) या नहीं अप्रासंगिक है। – Egwor

2

संक्षिप्त उत्तर नहीं है।

हार्डवेयर डिज़ाइन में, हम कह रहे थे, "घड़ी या रीसेट लाइन पर गेट न डालें - यह तर्क को अस्पष्ट करता है।" वही कारण उसी कारण लागू होता है।

लंबे उत्तर का इंतजार करना होगा, लेकिन "ScreetchinglyObvious Code" देखें।

+0

यहां संदर्भ के आधार पर, उपयोगकर्ता "एलिस्टेयर" सबसे अधिक संभावना है [एलिस्टेयर कॉकबर्न] (https://en.wikipedia.org/wiki/Alistair_Cockburn)। –

1

दरअसल मैं किसी भी उपलब्ध उत्तर से कभी खुश नहीं हूं, लेकिन चलिए उन्हें देखें। विकल्प दो मूल्यांकन प्रश्नों के चारों ओर बनाया गया है:

ई 1। ज्ञान तर्क तर्क से संबंधित कहां है?

ई 2। कोड के अगले पाठक कहां देखेंगे? (Screechingly Obvious Code)

कुछ विकल्प:

  • ग्राहक कोड (उद्देश्य यह है कि "नए SupportTicket" करता है) में। यह शायद व्यापार तर्क को नहीं जानता/नहीं जानता, या अन्यथा आप उस फैंसी कन्स्ट्रक्टर को बनाना नहीं चाहते हैं। यह व्यापार तर्क के लिए सही जगह है, तो यह कहना चाहिए:

    $ticket = new SupportTicket($customer, $title); 
    
    handleNewSupportTicket($ticket, ...other parameters...) 
    

    जहां, आदेश E2 की रक्षा के लिए, "handlenewSupportTicket" वह जगह है जहां कि व्यापार तर्क परिभाषित किया जाता है (और अगले प्रोग्रामर आसानी से कर सकते हैं इसे खोजें)।

  • समर्थन टिकट ऑब्जेक्ट, एक अलग व्यावसायिक कॉल के रूप में। निजी तौर पर, मैं इसके साथ वास्तव में खुश नहीं हूं, क्योंकि क्लाइंट कोड से दो कॉल हैं, जहां मानसिक विचार 1 चीज है।

    $ticket = new SupportTicket($customer, $title); 
    
    $ticket -> handleNewSupportTicket(...other parameters...) 
    
  • समर्थन टिकट की कक्षा में

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

    $ticket = SupportTicket.createAndHandleNewSupportTicket(...other parameters...) 
    

    है कि ग्राहक कोड अन्य प्रयोजनों के लिए नए टिकट (अन्यथा "$ करने के लिए संभाल की जरूरत मानते हुए टिकट = "गायब हो जाएगा)।

    मुझे इस बात का बहुत शौक नहीं है, क्योंकि अन्य प्रोग्रामर को क्लास या स्थैतिक तरीकों में व्यावसायिक तर्क देखने के लिए इतना स्वाभाविक नहीं लगता है। लेकिन यह तीसरी पसंद है।

  • एकमात्र चौथा विकल्प यह है कि यदि कोई अन्य स्थान है तो व्यवसाय तर्क खुशी से रहता है और अन्य प्रोग्रामर स्वाभाविक रूप से इसकी तलाश करेंगे, इस मामले में यह कक्षा/स्थैतिक कार्य में जाता है।

    $ticket = SupportTicketBusinessLogic.createAndHandleNewSupportTicket(...other params...) 
    

    जहां कक्षा/स्थैतिक फ़ंक्शन एकाधिक कॉल की आवश्यकता है। (लेकिन अब हम एक बार फिर से संभावना है कि टिकट का निर्माण किया जा सकता है और नहीं संभाला ठीक से :(है

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