2009-10-20 6 views
9

चिंताओं को अलग करने के लिए, मेरी वर्तमान परियोजना पर, मैंने अलग-अलग असेंबली में अपने डीएएल और बीएलएल/बिजनेस ऑब्जेक्ट्स को पूरी तरह से अलग करने का फैसला किया है। मैं चीजों को बेहद सरल रखने के लिए किसी भी तर्क के बिना अपनी व्यावसायिक वस्तुओं को सरल संरचनाओं के रूप में रखना चाहता हूं। मैं चाहूंगा कि मैं अपने व्यापार तर्क को अपने डीएएल से अलग रख सकूं। तो मेरा आवेदन मेरी वस्तुओं को लोड करने के लिए मेरे डीएएल को बताएगा, मेरा डीएएल डेटाबेस पर चला जाएगा और डेटा प्राप्त करेगा, ऑब्जेक्ट को डेटा के साथ पॉप्युलेट करेगा और फिर इसे मेरे बीएलएल में वापस भेज देगा।मुझे अपने ऑब्जेक्ट मॉडल को कैसे डिज़ाइन करना चाहिए ताकि मेरा डीएएल केवल-पढ़ने वाले फ़ील्ड को पॉप्युलेट कर सके?

प्रश्न - मैं एक अलग असेंबली में अपना डीएएल कैसे रख सकता हूं और केवल पढ़ने वाले फ़ील्ड में डेटा धक्का दे सकता हूं?

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

संपादित करें: मैं ध्यान दें मैं ObjectBase की वापसी प्रकार हो सकता है, लेकिन वास्तव में एक वस्तु या वस्तुओं है कि बाहर की दुनिया के लिए इतना रूप ObjectBase प्राप्त कर रहे हैं (मेरे दाल के बाहर) के संग्रह लौट कि गुण होगा केवल पढ़ने के लिए, लेकिन मेरे व्युत्पन्न प्रकार (केवल मेरे डीएएल के अंदर सुलभ) गुण वास्तव में पढ़/लिखते हैं।

+1

कोई कारण, यदि आप केवल अपनी व्यावसायिक वस्तुओं पर गुणों को पढ़ना चाहते हैं, तो आप उन्हें केवल निर्माता के माध्यम से सेट नहीं करते हैं? – CSharpAtl

+0

यदि आप स्क्रैच से अपना डीएलएल बनाने जा रहे हैं, तो मैं डिनो एस्पोजिटो और एंड्रिया साल्टेरेलो http://www.amazon.com/Microsoft%C2%AE- द्वारा "एंटरप्राइज़ .NET: एंटरप्राइज़ के लिए आर्किटेक्चरिंग एप्लिकेशन" को पढ़ने की अनुशंसा करता हूं। नेट-Architecting-आवेदन-प्रो-डेवलपर/डी पी/073562609X –

+0

@CSharpAtl यह सिर्फ मेरे लिए सही दृष्टिकोण का मन नहीं करता। – BobTheBuilder

उत्तर

7

आप एक निर्माता के माध्यम से केवल पढ़ने की संपत्ति सेट कर सकते हैं।

+1

यही वह है जो मैं सोच रहा था, लेकिन मुझे यह कहना है कि मुझे यह भी बेहतर नहीं लगता है। यह इस मुद्दे पर बैंड-एड्स डाल रहा है, यह अंतर्निहित समस्या को ठीक नहीं कर रहा है। – BobTheBuilder

+0

अपरिवर्तनीय वस्तुएं बिना किसी लाभ के काम करने के लिए दर्द हो सकती हैं। यानी वे एक वेब ऐप में उनका उपयोग कर रहे हैं। –

+0

@ चार्ल्स सहमत हैं, आप मेरे उत्तर के लिए बहुत सारे तर्क मिल सकते हैं ... – eglasius

0

इसके साथ बस कैसे रहें?

उन दिशानिर्देशों के साथ कार्यान्वित करें, लेकिन अपने मॉडल में इतनी कठोर बाधा न डालें। आइए कहें कि आप ऐसा करते हैं, लेकिन फिर एक और रिक्त आओ जहां आपको इसे क्रमबद्ध करने या कुछ और करने की आवश्यकता है, और फिर आप इसके साथ बंधे हैं।

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


अद्यतन 1: शायद "सिर्फ रहते हैं इसके साथ" बहुत साधारण था, लेकिन मैं अभी भी तनाव है कि तुम बहुत गहरा इन बातों में नहीं जाना चाहिए। सरल दिशानिर्देशों का उपयोग करके, अपने कोड को साफ रखें और शुरुआत में सबसे अच्छा कर सकते हैं। यह प्रगति के रास्ते में नहीं मिलेगा, जबकि सबकुछ अधिक सुलझाए जाने पर प्रतिक्रिया करना मुश्किल नहीं है।

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

आईएमएचओ यह महत्वपूर्ण वास्तुकला चिंताओं में फिट नहीं है जिसे शुरुआत में संबोधित करने की आवश्यकता है।

प्री-एम्प्टीव फॉलो अप: सावधान रहें यदि आप सरल दिशा-निर्देशों का पालन करने में अपनी टीम पर भरोसा नहीं कर सकते हैं। कुछ संरचनाओं के साथ शुरू करना भी सुनिश्चित करें, कुछ परिदृश्य चुनें जो वास्तविक सामग्री के साथ संरचना निर्धारित करते हैं, जब सरल कुछ होता है तो टीम अपने तरीके को बेहतर तरीके से जानती है।

+0

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

+0

मैं दोनों तरफ देख सकता हूं ... कई बार 'आदर्श' डिजाइन बहुत चरम है, कई मामलों में एक अच्छी तरह से संवाद सम्मेलन पर्याप्त हो सकता है। उस ने कहा - बशर्ते कि डीएएल के लिए रिपोजिटरी पैटर्न का पालन किया जाए - गुणों के 'सेट' को सीमित करने के लिए एक रास्ता खोजना पूरी तरह से उचित लगता है। – STW

+0

@BobThebuilder - एक अपडेट जोड़ा गया। – eglasius

1

यह एक चांदी की गोली के बिना एक स्थिति है, सबसे सरल विकल्प सीमित हैं या आपकी आवश्यकताओं को पूरा नहीं करते हैं और पूरी तरह से समाधान या तो गंध लगने लगते हैं या सादगी से दूर जाने लगते हैं।

शायद सबसे सरल विकल्प वह है जिसे मैंने यहां उल्लेख नहीं किया है: फ़ील्ड/गुणों को निजी रखते हुए और out/ByRef डीएएल के पैरामीटर के रूप में उन्हें पास कर रहा है। हालांकि यह बड़ी संख्या में खेतों के लिए काम नहीं करेगा, यह एक छोटी संख्या के लिए आसान होगा।

(मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह खोज करने लायक है)।

public class MyObject() 
{ 
    private int _Id; 
    public int Id { get { return _Id; } } // Read-only 

    public string Name { get; set; } 

    // This method is essentially a more descriptive constructor, using the repository pattern for seperation of Domain and Persistance 
    public static MyObject GetObjectFromRepo(IRepository repo) 
    { 
     MyObject result = new MyObject(); 
     return repo.BuildObject(result, out _Id);    
    } 
} 

public class MyRepo : IRepository 
{ 
    public MyObject BuildObject(MyObject objectShell, out int id) 
    { 
     string objectName; 
     int objectId; 

     // Retrieve the Name and Value properties 
     objectName = "Name from Database"; 
     objectId = 42; 
     // 

     objectShell.Name = objectName; 
     Console.WriteLine(objectShell.Id); // <-- 0, as it hasn't been set yet 
     id = objectId; // Setting this out parameter indirectly updates the value in the resulting object 
     Console.WriteLine(objectShell.Id); // <-- Should now be 42 
    } 
} 

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

+0

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

+0

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

1

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

मॉडल परियोजना

namespace Model 
{ 
    public class DataObject 
    { 
     public int id { get; protected set; } 
     public string name { get; set; } 
    } 
} 

डाटा परियोजना

namespace Data 
{ 
    class DALDataObject : DataObject 
    { 
     public DALDataObject(int id, string name) 
     { 
      this.id = id; 
      this.name = name; 
     } 
    } 
    public class Connector 
    { 
     public static DataObject LoadDataObject(int objectId) 
     { 
      return new DALDataObject(objectId, string.Format("Dummy object {0}", objectId)); 
     } 
     public static IEnumerable<DataObject> LoadDataObjects(int startRange, int endRange) 
     { 
      var list = new List<DataObject>(); 
      for (var i = startRange; i < endRange; i++) 
       list.Add(new DALDataObject(i, string.Format("Dummy object {0}", i))); 

      return list; 
     } 
    } 
} 
+0

हम्म, मैं अभी भी वास्तव में यकीन है कि मैं निर्माता है कि आप का उपयोग किया है की तरह है, हालांकि, यह सब गहन प्रयोजनों के लिए बाहर की दुनिया से निर्माता छुपाता है तो मैं मैं इस दृष्टिकोण की तरह लगता है नहीं कर रहा हूँ। मुझे यह तथ्य पसंद है कि यह मॉडल क्रमबद्धता को संबोधित करता है और एसओसी को रखता है और मुझे लगता है कि केवल पढ़ने वाले फ़ील्ड वास्तव में इस तरह रखे जाते हैं। धन्यवाद +1 – BobTheBuilder

+0

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

+0

@BobTheBuilder - कम से कम इस विधि मतलब है कि आप होशपूर्वक तय करने के लिए मुझे पता है कि इन गुणों सुरक्षित हैं और है कि मैं उन्हें करने के लिए लिखने के लिए इस करना चाहिए है। तो यह अनजाने त्रुटियों को रोकता है। – BenAlabaster

0

मेरी राय में, सबसे अच्छा तरीका यह संभाल करने के लिए व्यापार की वस्तुओं और में दाल है नामस्थान द्वारा अलग एक ही असेंबली। यह चिंताओं तार्किक अलग करती है और आप आंतरिक setters उपयोग करने के लिए अनुमति देता है। मैं उन्हें अपने स्वयं के असेंबली में अलग करने के किसी भी लाभ के बारे में नहीं सोच सकता क्योंकि एक दूसरे के बिना बेकार है।

+0

मुझे लगता है कि यह एक दृष्टिकोण है। हालांकि, यह मेरा विचार है कि तर्क परत को डेटा परत की आवश्यकता नहीं होनी चाहिए; डेटा परत को तर्क परत को उपयोगी होने की आवश्यकता नहीं होनी चाहिए; ऑब्जेक्ट परत को या तो तर्क परत या डेटा परत की आवश्यकता नहीं होती है क्योंकि यह केवल डेटा होना चाहिए; लेकिन डेटा लेयर और लॉजिक लेयर दोनों को ऑब्जेक्ट लेयर की आवश्यकता होगी क्योंकि उन्हें ऑब्जेक्ट्स पर काम करने की आवश्यकता है।इसलिए वस्तुओं को अपनी असेंबली में होना चाहिए, तर्क अपनी असेंबली में होना चाहिए और डेटा परत अपनी असेंबली में होनी चाहिए। – BobTheBuilder

+0

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

+0

हालांकि मेरी राय में, डीएएल पूरी तरह से अलग असेंबली होनी चाहिए, इस तरह जब आपके डेटा स्टोर को स्वैप करने की आवश्यकता होती है तो आपको केवल एक डीएलएल को प्रतिस्थापित करने की आवश्यकता होती है, आपको किसी और चीज को फिर से कंपाइल करने की आवश्यकता नहीं होती है। – BobTheBuilder

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

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