2009-01-19 5 views
23

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

अब मेरे पास एक अलग नामस्थान में निहित डेटाएप परत (डीएएल) है, प्रत्येक बीएलएल ऑब्जेक्ट के लिए मेरे पास डेटा क्लास या "रिपोजिटरी" है जो GetById निष्पादित करता है और कमांड को सहेजता है। तो एक तरह से, बीएलएल सेव करें और GetBd विधियां डेटा क्लास विधियों के चारों ओर एक पतली परत हैं।

public static NewsItem GetByID(int id) 
{ 
     return DataFactory.GetNewsItemRepository().GetNewsItemById(id); 
} 

डेटा क्लास बीएलएल वस्तुओं को वापस करने के लिए, उन्हें बीएलएल को जानने की आवश्यकता है। तो अब हमारे पास:

जीयूआई ---> BLL < ----> दाल

DataFactory केवल वस्तुओं है कि एक अंतरफलक को लागू देता है, तो मैं "OracleNewsItemRepository" की तरह कार्यान्वयन विवरण छुपा सकते हैं।

लेकिन अब ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग शुरू करने के बाद से मुझे उस चीज के लिए परेशान कर रहा है। मेरे वर्तमान समाधान में, बीएलएल और डीएएल दोनों को एक दूसरे को जानने की जरूरत है। यह एक परिपत्र निर्भरता है, और परिपत्र निर्भरताओं से बचने के लिए यह सबसे अच्छा अभ्यास है। इसके अलावा मैं केवल इंटरफेस (और मेरे डेटाफैक्टरी) का पर्दाफाश करना चाहता हूं, न कि मेरी कक्षाएं। यह एक अलग विधानसभा में डीएएल परत रखकर किया जा सकता है। जो समझ में आता है। हालांकि, विजुअल स्टूडियो दो असेंबली को एक दूसरे को संदर्भित करने की अनुमति नहीं देता है। इसके बारे में एक और सवाल: C# internal access modifiers

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

वे मेरी समस्या का समाधान नहीं करते हैं। शायद मैं थोड़ा गुदा हूं, और "सही डेटा एक्सेस पैटर्न" जैसी कोई चीज़ नहीं है। और अब मैं जो करता हूं वह बहुत गलत नहीं लगता है। लेकिन अब मैं चीजें कैसे करता हूं, लगता है ...

कोई विचार?

उत्तर

11

मुझे लगता है कि आपका डेटा एक्सेस पैटर्न ठीक है। आप जो नहीं कर रहे हैं वह आपके बीएलएल को ओरेकलडल में जोड़ रहा है। आप डीएएल इंटरफेस के साथ मिल रहे हैं। युग्मन का एक निश्चित बिट बिल्कुल जरूरी है या आप कभी भी कुछ नहीं कर पाएंगे।

मुझे लगता है कि आपके डेटाफैक्टरी और INewsItemRepository कक्षाएं आपके डीएएल परत के बाहर मौजूद हैं। निम्नलिखित एक उदाहरण है कि मेरे समाधान कैसे व्यवस्थित किए जाते हैं। मैं ActiveRecord का उपयोग नहीं करता, इसलिए यह आपको पूरी तरह से अनुकूल नहीं कर सकता है।

 
Core (Project) 
    Domain 
    Business Entities 
    Data 
    Repository Interfaces 
    **Your DataFactory** 

OracleData (Project) 
    Data 
    Oracle Repository Implementations 

SqlData (Project) 
    Data 
    Sql Repository Implementations 

UI (Project) 

उम्मीद है कि इससे मदद मिलती है।

+0

काम करता है, डीआई के साथ संयोजन में। मेरा बीएलएल अब इंटरफेस को जानता है। – IceHeat

11

मेरी राय में:

डेटा एक्सेस लेयर (दाल) Pocos पर काम करना चाहिए (सादा वर्ष CLR वस्तुओं) जैसे आपरेशन का उपयोग करते हुए: SaveNewsItem (NewsItemDAO newsItemDAO)। पीओसीओ आपके डीएओ (डेटा एक्सेस ऑब्जेक्ट्स) हैं।

बिजनेस लेयर में डेटा एक्सेस ऑब्जेक्ट (डीएओ) को समृद्ध व्यावसायिक ऑब्जेक्ट में परिवर्तित करने के लिए तर्क होना चाहिए, जो शायद डीएओ और कुछ संचालन के साथ-साथ सजावट/संवर्धन भी हो।

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

जैसा कि बताया गया है, डीएएल संचालन, उदा। SaveNewsItem को बीओ द्वारा इंटरफेस के माध्यम से एक्सेस किया जाना चाहिए, शायद निर्भरता इंजेक्शन/आईओसी के माध्यम से।

+0

हां, मैं सहमत हूं - यह बेहतर है कि डीएएल बीएलएल के बारे में नहीं जानता। इसके बजाय डीएएल के पास कुछ प्रकार का अमूर्त होना चाहिए ताकि बीएलएल अपने कच्चे डेटा 'यानी डीएओ (या एक्सएमएल या उदाहरण के लिए कुंजी/मूल्य जोड़े का नक्शा) से अपनी इकाइयां बना सके। इन कारखानों को डोमेन तर्क –

5

आप अपनी समस्या का समाधान करने के लिए इंटरफेस/निर्भरता इंजेक्शन का उपयोग कर सकते हैं।

आपकी व्यावसायिक परत (बीएल) में डाटा एक्सेस (डीए) इंटरफेस शामिल हैं जो (संभवतः एक से अधिक) डीएएल को कार्यान्वित करने की आवश्यकता है। डीएएल परियोजनाओं में बीएल के लिए परियोजना संदर्भ हैं ताकि वे व्यावसायिक वस्तुओं (बीओ) को थूक सकें और डीए इंटरफेस को कार्यान्वित कर सकें।

आपके बीओ डाटाफैक्टरी को कॉल कर सकते हैं, जो निर्भरता इंजेक्शन या प्रतिबिंब के माध्यम से डीए ऑब्जेक्ट को तुरंत चालू कर सकता है।

मैंने इस पैटर्न का उपयोग यहां हमारे कई अनुप्रयोगों (वेब-आधारित और स्मार्ट-क्लाइंट दोनों) पर किया है, और यह खूबसूरती से काम करता है।

+0

से बेहतर ढंग से अलग किया गया है, मैं इसे आज़मा दूंगा। – IceHeat

2

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

अपने व्यापार मॉडल के साथ अपने डीएएल में शून्य निर्भरताओं को प्राप्त करने का एक अच्छा तरीका है पहले से निर्मित ऑब्जेक्ट रिलेशन मैपिंग फ्रेमवर्क (ओआरएम) जैसे एनएचबर्ननेट (मेरे पसंदीदा ओआरएम फ्रेमवर्क के लिए एक लापरवाही प्लग) का उपयोग करना।

+0

धोखेबाज। सभी जानते हैं कि ईएफ एनबीबेरनेट से दस लाख गुना बेहतर है। [कवर के लिए डकिंग] – Jake

+1

ईएफ के अलावा, आपके पास एक बिजनेस मॉडल नहीं हो सकता है जो ईएफ पर निर्भरता से मुक्त हो। – Trent

+1

व्यापार परत लेनदेन के लिए ज़िम्मेदार है? नहीं, वे डीएएल में बने हैं। केवल एक अपवाद: वितरित लेनदेन। – Pascal

0

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

2

IceHeat, @Craig विल्सन के उदाहरण सबसे समझ में आता है और उसके शायद इस लेख से ली गई: http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

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

+0

यह एक अच्छा लेख है। मुझे यकीन नहीं है कि परियोजना संरचना कहां से आई थी, लेकिन मैंने एरिक इवान के "डोमेन संचालित डिजाइन" को कई बार पढ़ा है ... –

1

मैं आप से किसी भी प्राप्त करें() और सहेजें() विधि हटा BLL (डोमेन मॉडल) यहाँ .. मैं क्या कर सकता है

जीयूआई भंडार पूछना आईडी द्वारा डोमेन वस्तु प्राप्त करने के लिए होगा .. और एक बार जीयूआई डोमेन ऑब्जेक्ट है जिसे आप अन्य ऑब्जेक्ट्स तक पहुंचने के लिए नेविगेट कर सकते हैं .. इस तरह डोमेन परत को रिपॉजिटरीज़ के बारे में कुछ भी जानने की आवश्यकता नहीं है ..

रिपोजिटरी के अंदर आप डोमेन ऑब्जेक्ट वापस कर सकते हैं जो आलसी लोड ऑब्जेक्ट ग्राफ़ को आलसी लोड या पूरी तरह से लोड करता है। यह आपकी जरूरत पर निर्भर करेगा ..

यहां एक ही विषय पर एक अच्छा लिखना है ...Reconstituting objects

कैसे गतिशील प्रॉक्सी

3

यह थोड़ा अब पुरानी उपयोग करने पर देयान पेत्रोव द्वारा टिप्पणी पढ़ें लेकिन शायद आपको एक और विधानसभा में Pocos/इंटरफेस डालने पर विचार किया जाना चाहिए।

Project.Data references Project.Entities 
Project.BL references Project.Entities and Project.Data 
Project.UI references Project.Entities and Project.BL 

यहाँ कोई परिपत्र संदर्भ हैं।