क्या मैं इस वास्तुकला के साथ ओओपी अभ्यास को तोड़ रहा हूं?


23

मेरे पास एक वेब एप्लिकेशन है। मुझे विश्वास नहीं है कि प्रौद्योगिकी महत्वपूर्ण है। संरचना एक एन-टियर एप्लिकेशन है, जो बाईं ओर की छवि में दिखाया गया है। 3 परतें हैं।

UI (MVC पैटर्न), बिजनेस लॉजिक लेयर (BLL) और डेटा एक्सेस लेयर (DAL)

मेरे पास जो समस्या है वह मेरी बीएलएल है, यह बड़े पैमाने पर है क्योंकि इसमें एप्लिकेशन ईवेंट कॉल के माध्यम से तर्क और रास्ते हैं।

आवेदन के माध्यम से एक विशिष्ट प्रवाह हो सकता है:

UI में फंसी हुई घटना, BLL में एक विधि के लिए पार, तर्क प्रदर्शन (संभवतः BLL के कई हिस्सों में), अंततः DAL के लिए, वापस BLL (जहाँ संभवतः अधिक तर्क) और फिर UI के लिए कुछ मान लौटाते हैं।

इस उदाहरण में BLL बहुत व्यस्त है और मैं सोच रहा हूं कि इसे कैसे विभाजित किया जाए। मेरे पास तर्क और वस्तुएं भी हैं जो मुझे पसंद नहीं हैं।

यहाँ छवि विवरण दर्ज करें

दाईं ओर का संस्करण मेरा प्रयास है।

तर्क अभी भी कैसे आवेदन यूआई और दाल के बीच बहती है, लेकिन संभावित कोई गुण ... केवल विधियों (इस परत में कक्षाओं के बहुमत रहे सका संभवतः स्थिर हो क्योंकि वे किसी भी राज्य को संग्रहीत नहीं करते हैं)। पोको परत वह जगह है जहां कक्षाएं मौजूद होती हैं, जिनमें गुण होते हैं (जैसे कि व्यक्ति वर्ग जहां नाम, आयु, ऊंचाई आदि होगा)। आवेदन के प्रवाह से इनका कोई लेना-देना नहीं होता, वे केवल राज्य को संग्रहीत करते हैं।

प्रवाह हो सकता है:

यहां तक ​​कि UI से ट्रिगर किया गया और UI परत नियंत्रक (MVC) के लिए कुछ डेटा पास करता है। यह कच्चे डेटा का अनुवाद करता है और इसे पोको मॉडल में परिवर्तित करता है। पोको मॉडल को तब लॉजिक लेयर (जिसे BLL) में पास किया गया था और अंततः कमांड क्वेरी लेयर में, संभवतः रास्ते में हेरफेर किया गया। कमांड क्वेरी लेयर POCO को एक डेटाबेस ऑब्जेक्ट में परिवर्तित करता है (जो लगभग एक ही चीज है, लेकिन एक दृढ़ता के लिए डिज़ाइन किया गया है, दूसरा सामने के छोर के लिए)। आइटम संग्रहीत किया जाता है और एक डेटाबेस ऑब्जेक्ट को कमांड क्वेरी लेयर में लौटा दिया जाता है। इसे तब एक POCO में परिवर्तित कर दिया जाता है, जहां यह तर्क परत में लौटता है, संभवतः आगे संसाधित किया जाता है और फिर अंत में, UI पर वापस आ जाता है

साझा तर्क और इंटरफ़ेस वह जगह है जहाँ हमारे पास लगातार डेटा हो सकता है, जैसे कि MaxNumberOf_X और TotalAllowed_X और सभी इंटरफेस।

दोनों साझा तर्क / इंटरफेस और DAL वास्तुकला का "आधार" हैं। ये बाहरी दुनिया के बारे में कुछ नहीं जानते हैं।

साझा तर्क / इंटरफेस और डीएएल के अलावा पोको के बारे में सब कुछ पता है।

प्रवाह अभी भी पहले उदाहरण के समान है, लेकिन इसने प्रत्येक परत को 1 चीज़ के लिए अधिक ज़िम्मेदार बनाया है (यह राज्य, प्रवाह या कुछ और हो) ... लेकिन क्या मैं इस दृष्टिकोण के साथ ओओपी को तोड़ रहा हूं?

तर्क और पोको को प्रदर्शित करने के लिए एक उदाहरण हो सकता है:

public class LogicClass
{
    private ICommandQueryObject cmdQuery;
    public PocoA Method1(PocoB pocoB) 
    { 
        return cmdQuery.Save(pocoB); 
    }

    /*This has no state objects, only ways to communicate with other 
    layers such as the cmdQuery. Everything else is just function 
    calls to allow flow via the program */
    public PocoA Method2(PocoB pocoB) 
    {         
        pocoB.UpdateState("world"); 
        return Method1(pocoB);
    }

}

public struct PocoX
{
     public string DataA {get;set;}
     public int DataB {get;set;}
     public int DataC {get;set;}

    /*This simply returns something that is part of this class. 
     Everything is self-contained to this class. It doesn't call 
     trying to directly communicate with databases etc*/
     public int GetValue()
     {

         return DataB * DataC; 
     }

     /*This simply sets something that is part of this class. 
     Everything is self-contained to this class. 
     It doesn't call trying to directly communicate with databases etc*/
     public void UpdateState(string input)
     {        
         DataA += input;  
     }
}

जैसा कि आपने वर्तमान में वर्णन किया है, मुझे आपके आर्किटेक्चर के साथ मौलिक रूप से कुछ भी गलत नहीं दिखता है।
रॉबर्ट हार्वे

19
किसी भी अधिक जानकारी प्रदान करने के लिए आपके कोड उदाहरण में पर्याप्त कार्यात्मक विस्तार नहीं है। फ़ोबार उदाहरण शायद ही कभी पर्याप्त चित्रण प्रदान करते हैं।
रॉबर्ट हार्वे

1
आपके विचार के अधीन
थारोट

4
हम इस प्रश्न के लिए एक बेहतर शीर्षक मिल सकता है तो यह कर सकते हैं ऑनलाइन और अधिक आसानी से पाया जा?
सोनर ग्नूएल

1
बस पांडित्य होना: एक स्तरीय और एक परत एक ही बात नहीं है। एक "टियर" तैनाती के बारे में बोलता है, तर्क के बारे में एक "परत"। आपका डेटा लेयर सर्वर-साइड-कोड- और डेटाबेस-टियर्स दोनों के लिए तैनात किया जाएगा। आपकी UI परत वेब-क्लाइंट- और सर्वर-साइड-कोड-टियर्स दोनों के लिए तैनात की जाएगी। आपके द्वारा दिखाया गया आर्किटेक्चर एक 3-लेयर आर्किटेक्चर है। आपके टियर "वेब क्लाइंट", "सर्वर साइड कोड" और "डेटाबेस" हैं।
लॉरेंट ला रिज़्ज़ा

जवाबों:


54

हां, आप बहुत संभवत: कोर को तोड़ रहे हैं OOP अवधारणाओं को । हालांकि, बुरा नहीं लगता है, लोग हर समय ऐसा करते हैं, इसका मतलब यह नहीं है कि आपकी वास्तुकला "गलत" है। मैं कहूंगा कि यह एक उचित OO डिजाइन की तुलना में शायद कम रखरखाव योग्य है, लेकिन यह बल्कि व्यक्तिपरक है और वैसे भी आपका प्रश्न नहीं है। ( यहाँ n-tier वास्तुकला की सामान्य रूप से आलोचना करते हुए मेरा एक लेख है)।

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

निश्चित रूप से हमेशा अपवाद होते हैं, लेकिन यह डिजाइन इन चीजों को एक नियम के रूप में उल्लंघन करता है।

फिर से, मैं "ओओपी का उल्लंघन करता हूं!" पर जोर देना चाहूंगा! = "गलत", इसलिए यह जरूरी नहीं कि एक मूल्य निर्णय हो। यह सब आपके आर्किटेक्चर की कमी, स्थिरता के उपयोग-मामलों, आवश्यकताओं आदि पर निर्भर करता है।


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

2
@ TheCatWhisperer: आधुनिक उद्यम आर्किटेक्चर पूरी तरह से ओओपी को नहीं फेंकते हैं, बस चुनिंदा (जैसे डीटीओ के लिए)।
रॉबर्ट हार्वे


@ TheCatWhisperer एक oop में कई फायदे हैं जैसे c # भाषा के oop हिस्से में जरूरी नहीं है, लेकिन उपलब्ध समर्थन में जैसे लाइब्रेरी, विजुअल स्टूडियो, मेमोरी मैनेजमेंट आदि

@Orangesandlemons मुझे यकीन है कि वहाँ अन्य अच्छी तरह से समर्थित भाषाओं के बहुत सारे हैं ...
TheCatWhisperer

31

कार्यात्मक प्रोग्रामिंग के मूल सिद्धांतों में से एक शुद्ध कार्य है।

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के मूल सिद्धांतों में से एक उन कार्यों के साथ मिलकर कार्य कर रहा है, जिन पर वे कार्य करते हैं।

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

इसलिए डेटा केवल "ऑब्जेक्ट्स" के लिए ठीक है जिसे आप इधर-उधर फेंक रहे हैं क्योंकि आपको उन्हें एक सीमा पार करने की आवश्यकता है जिसे आप केवल इच्छुक कोड को स्थानांतरित करने के लिए रिफ्लेक्टर नहीं कर सकते हैं। बस पता है कि OOP नहीं है। यही वास्तविकता है। OOP है, जब एक बार उस सीमा के अंदर आप उस डेटा पर काम करने वाले सभी तर्क इकट्ठा करते हैं।

ऐसा नहीं है कि आपको ऐसा करना होगा। OOP सभी लोगों के लिए सभी चीजें नहीं हैं। यह है जो यह है। बस यह दावा न करें कि OOP का अनुसरण कुछ तब होता है जब आप अपना कोड बनाए रखने की कोशिश कर रहे लोगों को भ्रमित करते हैं या नहीं करते हैं।

आपके POCO के लिए उनमें व्यावसायिक तर्क ठीक प्रतीत होते हैं इसलिए मैं एनीमिक होने के बारे में बहुत अधिक चिंता नहीं करूंगा। मुझे क्या चिंता है कि वे सभी बहुत ही परस्पर मिल रहे हैं। याद रखें कि गेटर्स और सेटर असली इनकैप्सुलेशन प्रदान नहीं करते हैं। यदि आपका POCO उस सीमा के लिए है तो ठीक है। बस यह समझ लें कि यह आपको वास्तविक एनकैप्सुलेटेड OOP ऑब्जेक्ट का पूर्ण लाभ नहीं दे रहा है। कुछ लोग इसे डेटा ट्रांसफर ऑब्जेक्ट या डीटीओ कहते हैं।

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

मैं गेटर्स या सेटर प्रदान नहीं करता। मैं बताता हूं, मत पूछो । आप मेरे तरीकों को कहते हैं और वे वही करते हैं जो करने की जरूरत है। उन्होंने संभवतः यह भी नहीं बताया कि उन्होंने क्या किया। वे बस करते हैं।

अब अंततः कुछ, कहीं और एक और सीमा में जा रहा है और यह सब फिर से अलग हो जाता है। कोई बात नहीं। एक अन्य डीटीओ को स्पिन करें और इसे दीवार पर टॉस करें।

बंदरगाहों और एडाप्टरों की वास्तुकला के बारे में यही सार है। मैं इसके बारे में एक कार्यात्मक दृष्टिकोण से पढ़ रहा हूं । शायद यह आपको भी रूचि देगा।


5
" गेटर्स एंड सेटर्स असली एनकैप्सुलेशन प्रदान नहीं करते हैं " - हाँ!
बोरिस स्पाइडर

3
@BoristheSpider - गेटर्स और सेटर्स पूरी तरह से इनकैप्सुलेशन प्रदान करते हैं, वे सिर्फ एनकैप्सुलेशन की आपकी संकीर्ण परिभाषा को फिट नहीं करते हैं।
.dralo

4
@ Davor asdralo: वे कभी-कभार वर्कअराउंड के रूप में उपयोगी होते हैं, लेकिन उनकी बहुत ही प्रकृति से, गेटअप और सेटर्स ब्रेक इनकैप्सुलेशन। कुछ आंतरिक चर प्राप्त करने और सेट करने का एक तरीका प्रदान करना आपके अपने राज्य के लिए जिम्मेदार होने और उस पर अभिनय करने के लिए विपरीत है।
cHao

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

4
@cHao - एनकैप्सुलेशन का मतलब है कि आप कार्यान्वयन को छिपा रहे हैं। जो कि अतिक्रमित हो जाता है। यदि आपके पास स्क्वायर क्लास पर "getSurfaceArea ()" गेट्टर है, तो आपको पता नहीं है कि क्या सतह क्षेत्र एक फ़ील्ड है, अगर यह मक्खी (वापसी ऊंचाई * चौड़ाई) या कुछ तीसरी विधि पर गणना की जाती है, तो आप आंतरिक कार्यान्वयन को बदल सकते हैं किसी भी समय आप की तरह, क्योंकि यह समझाया है।
.dralo

1

यदि मैं आपकी व्याख्या को सही ढंग से पढ़ता हूं तो आपकी वस्तुएं कुछ इस तरह दिखती हैं: (बिना संदर्भ के मुश्किल)

public class LogicClass
{
    private ICommandQueryObject cmdQuery;
    public PocoA Method(PocoB pocoB) { ... }
}

public class PocoX
{
     public string DataA {get;set;}
     public int DataB {get;set;}
     ... etc
}

इसमें आपके पोको वर्गों में केवल डेटा होता है और आपके तर्क वर्गों में वे विधियाँ होती हैं जो उस डेटा पर कार्य करती हैं; हाँ, आपने "क्लासिक OOP" के सिद्धांतों को तोड़ दिया है

फिर, आपके सामान्यीकृत विवरण से बताना कठिन है, लेकिन मुझे खतरा होगा कि आपने जो लिखा है उसे एनीमिक डोमेन मॉडल के रूप में वर्गीकृत किया जा सकता है।

मुझे नहीं लगता कि यह एक विशेष रूप से बुरा दृष्टिकोण है, न ही, यदि आप अपने पोको के रूप में विचार करते हैं तो यह अधिक विशिष्ट अर्थों में ओओपी को तोड़ता है। इसमें आपकी वस्तुएँ अब LogicClasses हैं। वास्तव में यदि आप अपने Pocos को अपरिवर्तनीय बनाते हैं तो डिज़ाइन को काफी कार्यात्मक माना जा सकता है।

हालाँकि, जब आप साझा किए गए तर्क, Pocos का संदर्भ देते हैं, जो लगभग नहीं बल्कि समान और स्टैटिक्स हैं, तो मुझे आपके डिज़ाइन के विस्तार के बारे में चिंता होने लगती है।


मैंने अपने पोस्ट में जोड़ा है, अनिवार्य रूप से आपके उदाहरण की नकल करते हुए। क्षमा करें ti के साथ शुरू करने के लिए स्पष्ट नहीं था
MyDaftQuestions

1
मेरा क्या मतलब है, अगर आपने हमें बताया कि आवेदन क्या करता है तो उदाहरण लिखना आसान होगा। लॉजिकक्लास के बजाय आप पेमेंटप्रोवाइडर या जो भी हो
इवान

1

एक संभावित समस्या जो मैंने आपके डिज़ाइन में देखी (और यह बहुत सामान्य है) - कुछ सबसे खराब "OO" कोड जो मैंने कभी भी सामना किया है, वह एक आर्किटेक्चर के कारण हुआ था जिसने "डेटा" ऑब्जेक्ट्स को "कोड" ऑब्जेक्ट्स से अलग कर दिया था। यह बुरा सपना स्तर का सामान है! समस्या यह है कि आपके व्यवसाय कोड में हर जगह जब आप अपने डेटा ऑब्जेक्ट्स तक पहुंचना चाहते हैं, तो आप इसे सही कोड इनलाइन पर भेज दें (आपको इसकी आवश्यकता नहीं है, आप इसे संभालने के लिए एक उपयोगिता वर्ग या कोई अन्य फ़ंक्शन बना सकते हैं लेकिन यह वही है मैंने देखा है समय के साथ बार-बार होता है)।

एक्सेस / अपडेट कोड आमतौर पर एकत्रित नहीं होता है इसलिए आप हर जगह डुप्लिकेट कार्यक्षमता के साथ समाप्त होते हैं।

दूसरी ओर, वे डेटा ऑब्जेक्ट उपयोगी होते हैं, उदाहरण के लिए डेटाबेस दृढ़ता के रूप में। मैंने तीन समाधान आज़माए हैं:

"वास्तविक" ऑब्जेक्ट में मानों को बाहर और अपनी डेटा ऑब्जेक्ट को फेंकना थकाऊ है (लेकिन अगर आप इस तरह से जाना चाहते हैं तो एक वैध समाधान हो सकता है)।

डेटा ऑब्जेक्ट्स के लिए डेटा वंचन के तरीकों को जोड़ना काम कर सकता है लेकिन यह एक बड़ी गड़बड़ डेटा ऑब्जेक्ट के लिए बना सकता है जो एक से अधिक काम कर रहा है। यह भी मुश्किल बना सकता है क्योंकि कई दृढ़ता तंत्र सार्वजनिक एक्सेसर्स चाहते हैं ... मुझे यह पसंद नहीं है जब मैंने इसे किया है, लेकिन एक उचित समाधान

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

दूसरा फायदा यह है कि आप यह सुनिश्चित कर सकते हैं कि आपका डेटा वर्ग हमेशा वैध स्थिति में हो। यहाँ एक त्वरित psuedocode उदाहरण है:

// Data Class
Class User {
    String name;
    Date birthday;
}

Class UserHolder {
    final private User myUser // Cannot be null or invalid

    // Quickly wrap an object after getting it from the DB
    public UserHolder(User me)
    {
        if(me == null ||me.name == null || me.age < 0)
            throw Exception
        myUser=me
    }

    // Create a new instance in code
    public UserHolder(String name, Date birthday) {
        User me=new User()
        me.name=name
        me.birthday=birthday        
        this(me)
    }
    // Methods access attributes, they try not to return them directly.
    public boolean canDrink(State state) {
        return myUser.birthday.year < Date.yearsAgo(state.drinkingAge) 
    }
}

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

मैं डेटा ऑब्जेक्ट का विस्तार नहीं कर रहा हूं, क्योंकि आप इस इनकैप्सुलेशन और सुरक्षा की गारंटी को खो देते हैं - उस बिंदु पर आप डेटा वर्ग में केवल विधियों को जोड़ सकते हैं।

इस तरह से आपके व्यावसायिक तर्क में डेटा एक्सेस जंक / पुनरावृत्तियों का एक समूह नहीं होता है, यह बहुत अधिक पठनीय और कम निरर्थक हो जाता है। मैं हमेशा एक ही कारण के लिए संग्रह लपेटने की आदत में शामिल होने की सलाह देता हूं - लूपिंग / खोज को अपने व्यावसायिक तर्क से बाहर रखना और यह सुनिश्चित करना कि वे हमेशा एक अच्छी स्थिति में हों।


1

अपना कोड कभी न बदलें क्योंकि आपको लगता है या कोई आपको बताता है कि यह ऐसा है या नहीं। अपना कोड बदलें अगर यह आपको समस्याएं देता है और आपने दूसरों को बनाए बिना इन समस्याओं से बचने का एक तरीका निकाला है।

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


0

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

उस ने कहा, आपके उदाहरण के लिए:

मुझे लगता है कि एमवीसी का मतलब क्या है, इसके बारे में गलतफहमी है। आप अपने यूआई को "एमवीसी" कह रहे हैं, अपने व्यापार तर्क और "बैकएंड" नियंत्रण से अलग। लेकिन मेरे लिए, MVC में संपूर्ण वेब अनुप्रयोग शामिल हैं:

  • मॉडल - व्यवसाय डेटा + तर्क समाहित करता है
    • मॉडल के कार्यान्वयन विवरण के रूप में डेटा परत
  • देखें - यूआई कोड, एचटीएमएल टेम्पलेट, सीएसएस आदि।
    • जावास्क्रिप्ट जैसे क्लाइंट-साइड पहलू, या "एक-पृष्ठ" वेब एप्लिकेशन आदि के लिए पुस्तकालय शामिल हैं।
  • नियंत्रण - अन्य सभी भागों के बीच सर्वर-साइड गोंद
  • (यहां ViewModel, बैच आदि जैसे एक्सटेंशन हैं जो मैं यहां नहीं जाऊंगा)

यहाँ कुछ अत्यधिक महत्वपूर्ण आधार धारणाएँ हैं:

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

महत्वपूर्ण रूप से: UI MVC का एक हिस्सा है। दूसरे तरीके से नहीं (अपने आरेख की तरह)। यदि आप इसे गले लगाते हैं, तो वसा मॉडल वास्तव में बहुत अच्छे हैं - बशर्ते कि वे वास्तव में सामान नहीं रखते हैं जो उन्हें नहीं होना चाहिए।

ध्यान दें कि "वसा मॉडल" का अर्थ है कि सभी व्यावसायिक तर्क मॉडल श्रेणी में हैं (पैकेज, मॉड्यूल, जो भी आपकी पसंद की भाषा में नाम है)। अलग-अलग वर्गों को स्पष्ट रूप से OOP-संरचित होना चाहिए जो आपके द्वारा दिए गए कोडिंग दिशानिर्देशों के अनुसार एक अच्छा तरीका है (यानी, प्रति वर्ग या कुछ अधिकतम लाइनें-प्रति विधि, आदि)।

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

अपने प्रश्न पर वापस जाने के लिए: मुझे ऐसा लगता है कि आपकी नई वास्तुकला और मेरे द्वारा बताई गई एमवीसी योजना के बीच एक बड़ा ओवरलैप है, इसलिए आप पूरी तरह से गलत रास्ते पर नहीं हैं, लेकिन आप या तो कुछ सामानों को फिर से बनाना चाहते हैं, या इसका उपयोग करते हुए क्योंकि आपके वर्तमान प्रोग्रामिंग वातावरण / पुस्तकालय ऐसे सुझाव देते हैं। मेरे लिए कहना मुश्किल है। इसलिए मैं आपको इस बात का सटीक जवाब नहीं दे सकता कि आप जो चाहते हैं वह विशेष रूप से अच्छा है या बुरा। आप यह जाँच कर पता लगा सकते हैं कि क्या हर एक "चीज" के पास इसके लिए ठीक एक वर्ग है; क्या सब कुछ अत्यधिक सामंजस्यपूर्ण और कम युग्मित है। यह आपको एक अच्छा संकेत देता है, और, मेरी राय में, एक अच्छा ओओपी डिज़ाइन (या यदि आप चाहें तो उसी का एक अच्छा बेंचमार्क) के लिए पर्याप्त है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.