मुझे समझौता करना होगा: DRY, या कमांड-क्वेरी-सेपरेशन?


10

मैं हाल ही में एक विधि को फिर से शुरू कर रहा था जो एक कमांड और एक क्वेरी विधि थी।

एक कमांड विधि और एक क्वेरी विधि में इसे अलग करने के बाद, मैंने पाया कि कोड में अब कई जगह हैं जहां मैं कमांड को कॉल कर रहा हूं, फिर क्वेरी से मान प्राप्त करना, जो DRY सिद्धांत के उल्लंघन की तरह लगता है।

लेकिन अगर मैं उस कॉमन कोड को एक विधि में लपेटता, तो वह तरीका कमांड और क्वेरी दोनों होता। क्या यह स्वीकार्य है?


ठीक है, मुझे नहीं पता था कि समुदाय एक आम सहमति पर था, और मुझे इस विषय की कोई चर्चा नहीं मिली।
क्रिस वेल्श

इसे सामान्यतः CQRS google.com.au/…
डैनियल लिटिल

@DanielLittle - नहीं, यह नहीं है। CQS और CQRS अलग-अलग विषय हैं। CQRS एक बहुत अधिक शामिल वास्तुशिल्प पैटर्न है, जबकि CQS डिज़ाइन पैटर्न का अधिक है और इसे समझना और कार्यान्वित करना बहुत आसान है। कोडबेटेर
एरिक फ़नकेनबश

@ एरिक फ़नकेनबश आप सही हैं
डैनियल लिटिल

जवाबों:


11

परस्पर विरोधी डिजाइन सिद्धांतों के बीच विचार करने के लिए हमेशा व्यापार नापसंद होते हैं। इसे हल करने का तरीका सिद्धांतों के पीछे अंतर्निहित कारणों को देखना है। इस स्थिति में, कमांड को चलाए बिना क्वेरी को चलाने में असमर्थ होना समस्याग्रस्त है, लेकिन क्वेरी को चलाए बिना कमांड को चलाने में असमर्थ होना आमतौर पर हानिरहित है। जब तक क्वेरी स्टैंडअलोन को चलाने का एक तरीका है, मुझे कोई कारण नहीं दिखता है कि क्वेरी परिणाम को कमांड में न जोड़ें, खासकर अगर ऐसा कुछ किया जाए:

QueryResult command()
{
   // do command stuff
   return query();
}

4

मैंने पहले कमांड-क्वेरी-सेपरेशन (CQS) के बारे में नहीं सुना है, लेकिन ऐसा लगता है कि यह सिंगल रिस्पॉन्सिबिलिटी प्रिंसिपल (SRP) से संबंधित होगा, जिसमें कहा गया है कि एक फ़ंक्शन / क्लास आदर्श रूप से केवल एक काम और एक चीज़ करने के लिए ज़िम्मेदार होना चाहिए ।

यदि आपका कमांड कोड 20 लाइनों का कोड है और क्वेरी कोड एक और 30 लाइनें हैं और वे सभी एक फ़ंक्शन बॉडी में हैं, स्पष्ट रूप से आप SRP का उल्लंघन कर रहे हैं और मैं CQS को भी मान लूंगा और तर्क के उन दो टुकड़ों को एक दूसरे से अलग कर दिया जाना चाहिए ।

हालांकि, आपके काल्पनिक उदाहरण के साथ, मैं सबसे अधिक संभावना एक आवरण विधि बनाऊंगा जो आपके आदेश और क्वेरी को संयोजित करेगा ताकि DRY कोड में कई स्थानों पर उल्लंघन न हो। मैं इसे SRP (और शायद CQS) उल्लंघन भी नहीं मानूंगा, क्योंकि आवरण में अभी भी केवल एक ही जिम्मेदारी है: एक क्वेरी के साथ कमांड को संयोजित करना और एक उच्च स्तर का अमूर्त बनाना जो उपभोग करने में आसान है।

मुझे लगता है कि आवरण विधि पूरी तरह से स्वीकार्य समाधान है और यह स्पष्ट करने के लिए कि चलो अपने उदाहरण को एक कदम आगे ले जाएं। क्या होगा अगर आपको 1 के बजाय 2 क्वेरी को चलाना था और फिर उसके आधार पर कमांड एक्शन करना होगा। तो आपके कोड की 2 पंक्तियाँ 6 या 8 होंगी। क्या होगा यदि एक और के बीच कुछ डेटा सत्यापन / जाँच हो रही है, तो अब आपके पास कोड की 15 लाइनें हैं। क्या आप एक रैपर बनाने के बारे में दो बार सोचेंगे जो उन सभी 15 पंक्तियों को कई फाइलों में छिड़कने के बजाय करता है?


मुझे लगता है कि एक आवरण का "एकल सिद्धांत" अन्य तरीकों को रखने के लिए होना चाहिए जो कमांड और क्वेरी को एक साथ DRY चाहिए।
दरोगान्स


जबकि कार्ल की इस समस्या का हल बेहतर है, मुझे लगता है कि यह आपके विस्तार के लिए लंबे समय तक रैपर फ़ंक्शंस है।
क्रिस वेल्श

-3

DRY अधिक महत्वपूर्ण है, क्योंकि यह बहुत अधिक मूलभूत आवश्यकता को हल करता है - अनावश्यक रूप से, प्रभावी रूप से व्यर्थ प्रयास से बचना। यह एक बुनियादी बात है - इसे समझने के लिए एक प्रोग्रामर की आवश्यकता नहीं है।

CQS, ट्रैकिंग कोड के लिए बिना किसी समर्थन के, कठिनाई के लिए एक प्रतिक्रिया है, उस कोड को समझने के लिए जिसे इसके परिणामों और इसके प्रभावों दोनों के लिए निष्पादित किया जाता है। तथापि:

  1. इसके परिणामों के लिए कोड निष्पादित करने की आवश्यकता को टाला नहीं जा सकता है, क्योंकि यह छोटी इकाइयों से बड़े कार्यक्रमों की रचना का आधार है।

  2. इसके प्रभावों के लिए कोड निष्पादित करने की आवश्यकता को भी टाला नहीं जा सकता, क्योंकि, गणित और सैद्धांतिक कंप्यूटर विज्ञान के बाहर, एक प्रोग्राम चलाने का मूल्य हमारे लिए क्या करता है, इस पर निहित है।

  3. एक ही कोड में प्रभाव पैदा करने और परिणाम उत्पन्न करने की आवश्यकता को टाला नहीं जा सकता है, क्योंकि, व्यवहार में, हमें प्रभाव और संरचना दोनों की आवश्यकता है, न कि केवल एक या दूसरे की।

ट्रैकिंग प्रभाव की समस्या का वास्तविक समाधान अनियंत्रित मनुष्यों के लिए बहुत कठिन है, निश्चित रूप से, कंप्यूटरों द्वारा हमें मनुष्यों की सहायता के लिए है ! इसी तरह की बात रनटाइम वैल्यूज़ (जैसे एरे इंडेक्स की वैधता) के बीच जटिल रिश्तों को ट्रैक करने के बारे में कहा जा सकता है , जिसके लिए अपवाद और रनटाइम-एनफोर्समेंट कॉन्ट्रैक्ट्स (गैर-) समाधान होते हैं।

निष्कर्ष में, CQS की तरह "समाधान" केवल वास्तविकता के आधार पर ध्वनि सिद्धांतों के अनुसार कार्यक्रमों को डिजाइन करने के तरीके में मिलता है। DRY के लिए जाएं।


कभी-कभी आपको जटिलता को कम करने के लिए युग्मन से बचने की आवश्यकता होती है। आपको CQRS पर एक नज़र डालनी चाहिए।
डैनियल लिटिल

@Lavinski: जटिलता से बचने के लिए सबसे अच्छा उपकरण (इसे कम नहीं करना, जो कि व्यर्थ है) अमूर्तता है - हम उन समस्याओं के जेनेरिक सार को डिकम्पोज कर रहे हैं जो हमारे द्वारा बताई गई जेनेरिक समस्याओं के उदाहरणों के विशेष विवरण से हल हो रहे हैं। जादुई व्यंजनों (या "डिजाइन पैटर्न" जैसा कि मैंने सुना है कि वे कहते हैं) आपको अपने डिजाइन को गलत होने पर बहुत अधिक नुकसान होने से रोक सकते हैं, लेकिन वे गलत डिजाइन को सही में नहीं बदल सकते।
pyon

@Lavinski: विशेष रूप से CQRS के संबंध में, वैचारिक रूप से सही वैकल्पिक समाधान है 1. डेटा मॉडल को समझें (ऑब्जेक्ट लेयर्स की कोई भी मात्रा इसके लिए आवश्यकता को समाप्त नहीं कर सकती है), 2. डेटाबेस में दर्ज किए गए अनुसार कई शुद्धता गुणों को एनकोड करें। (अफसोस की बात है, सबसे लोकप्रिय RDBMS उत्तरार्द्ध के लिए सीमित समर्थन प्रदान करते हैं, न कि NoSQL वालों का उल्लेख करने के लिए, जो कि और भी गलत है। मेरा वर्तमान शोध इसके लिए एक बेहतर समाधान प्रदान कर रहा है।)
pyon

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

1
@ EduardoLeón: यदि आप अपने डिजाइन को सही साबित करना चाहते हैं, तो अपने कार्यक्रम के लिए परीक्षण लिखने का प्रयास करें। मैं आपको गारंटी दे सकता हूं कि सीक्यूएस को बाहर फेंकना केवल उस में आपके प्रयासों को बाधित करेगा।
स्टीफन बिलियट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.