2009-03-13 11 views
15

मैं ऐसा करने का सबसे साफ तरीका जानने का प्रयास कर रहा हूं।बिजनेस ऑब्जेक्ट में डेटा एक्सेस लेयर के लिए सर्वश्रेष्ठ "पैटर्न"

public class Customer 
{ 
    public int Id {get;set;} 
    public string name {get;set;} 
    public List<Email> emailCollection {get;set} 
    public Customer(int id) 
    { 
     this.emailCollection = getEmails(id); 
    } 
} 

तब मेरे ईमेल वस्तु भी सुंदर बुनियादी है:

वर्तमान में मैं एक ग्राहक वस्तु है।

public class Email 
{ 
    private int index; 
    public string emailAddress{get;set;} 
    public int emailType{get;set;} 
    public Email(...){...} 
    public static List<Email> getEmails(int id) 
    { 
     return DataAccessLayer.getCustomerEmailsByID(id); 
    } 
} 

DataAccessLayer वर्तमान डेटा बेस से जोड़ता है, और परिणाम सेट से अधिक पुनरावृति करने के लिए एक SqlDataReader का उपयोग करता है और नए ईमेल वस्तुओं बनाता है और उन्हें एक सूची है जो इसे लौटाता है जब किया करने के लिए कहते हैं।

तो मैं इस पर कहां और कैसे सुधार कर सकता हूं?

क्या मेरे पास डेटाएक्सेलेयर है, इसके बजाय मुझे डेटाटेबल लौटाएं और ईमेल ऑब्जेक्ट पर इसे पार्स करने के लिए छोड़ दें और एक सूची वापस ग्राहक को वापस कर दें?

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

क्या यह मेरे ईमेल.getEmails (id) को स्थिर विधि के रूप में रखने का भी उचित अभ्यास है?

मैं सामान्य रूप से एक साधारण कार्य के लिए सर्वोत्तम "पैटर्न" खोजने और लागू करने की कोशिश करके खुद को फेंक सकता हूं।

धन्यवाद।


अनुवर्ती

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

हालांकि, मैंने एक बड़ा प्रदर्शन हिट देखा है।

मेरी मूल विधि में डीबी पर एक संग्रहित प्रक्रिया शामिल थी, जिसे एक डीएएल ऑब्जेक्ट द्वारा बुलाया गया था, जिसने परिणाम को मेरे डोमेन/व्यावसायिक ऑब्जेक्ट में सेट किया था।

मैंने एक एकल ग्राहक रिकॉर्ड प्राप्त करने के लिए 30ms लेने में अपनी मूल विधि देखी। फिर मैंने एक ही रिकॉर्ड को पकड़ने के लिए 3000ms लेने में निहिरनेट विधि देखी।

क्या मुझे कुछ याद आ रही है? या क्या इस निबर्ननेट मार्ग का उपयोग करके बहुत अधिक ओवरहेड है?

अन्यथा मैं कोड की सफाई की तरह:

protected void Page_Load(object sender, EventArgs e) 
{ 
    ICustomerRepository repository = new CustomerRepository(); 
    Customer customer = repository.GetById(id); 
} 

public class CustomerRepository : ICustomerRepository 
     { 
      public Customer GetById(string Id) 
      { 
       using (ISession session = NHibernateHelper.OpenSession()) 
       { 
        Customer customer = session 
             .CreateCriteria(typeof(Customer)) 
             .Add(Restrictions.Eq("ID", Id)) 
             .UniqueResult<Customer>(); 
        return customer; 
       } 
      } 
     } 

example I followed मेरी मदद करने के लिए सत्र का प्रबंधन है, शायद यही कारण है कि मैं इस भूमि के ऊपर हो रही है एक सहायक वर्ग बनाने की थी?

public class NHibernateHelper 
    { 
     private static ISessionFactory _sessionFactory; 
     private static ISessionFactory SessionFactory 
     { 
      get 
      { 
       if (_sessionFactory == null) 
       { 
        Configuration cfg = new Configuration(); 
        cfg.Configure(); 
        cfg.AddAssembly(typeof(Customer).Assembly); 
        _sessionFactory = cfg.BuildSessionFactory(); 
       } 
       return _sessionFactory; 
      } 

     } 

     public static ISession OpenSession() 
     { 
      return SessionFactory.OpenSession(); 
     } 
    } 

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

अभी भी सुझावों के लिए खुला है!


अपडेट किया गया।

मैं अपना ओआरएम/एनएचबीरनेट मार्ग स्क्रैप कर रहा हूं। मैंने पाया कि प्रदर्शन इसका उपयोग करने के लिए उचित है। बुनियादी ग्राहक प्रश्न हमारे पर्यावरण के लिए बहुत अधिक समय लेते हैं। उप-सेकंड प्रतिक्रियाओं की तुलना में 3 सेकंड बहुत अधिक है।

अगर हम धीमी क्वेरी चाहते थे, तो हम केवल हमारे वर्तमान कार्यान्वयन को बनाए रखेंगे। इसे फिर से लिखने का विचार समय में भारी वृद्धि करना था।

हालांकि, पिछले हफ्ते एनएचबर्ननेट के साथ खेला जाने के बाद, यह एक अच्छा उपकरण है! यह सिर्फ इस परियोजना के लिए मेरी जरूरतों के अनुरूप नहीं है।

+0

बैरी- हाँ यह अभी ठीक काम कर रहा है। केवल एक चीज जिसे मैं सोच सकता हूं वह है कि मेरा DataAccessLayer डेटाटेबल लौटाता है, ताकि मैं डेटा एक्सेस लेयर के बजाय अपने व्यवसाय परत (यानी ईमेल ऑब्जेक्ट) में सत्यापन जांच कर सकूं। –

+1

आपके द्वारा पोस्ट किया गया उदाहरण क्लासिक "एनीमिक डोमेन मॉडल" है। आपके उदाहरण के आधार पर आपको किसी व्यापार वस्तु की भी आवश्यकता नहीं है। एक व्यापार वस्तु को व्यावसायिक तर्क रखना चाहिए, और आपका नहीं है। –

उत्तर

6

यदि कॉन्फ़िगरेशन अब आपके पास है, तो इसके साथ गड़बड़ क्यों करें? ऐसा लगता है कि आप कोड के साथ किसी भी विशेष जरूरतों या मुद्दों की पहचान नहीं कर रहे हैं।

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

+0

मैं खुद को एक ओओ लड़का मानता हूं, लेकिन मैं दृढ़ता से सहमत हूं। वर्तमान समाधान इतना आसान है कि मैं इसे भी समझ सकता हूं, जो निश्चित रूप से अच्छी गुणवत्ता है! – Treb

+2

एक सुझाव व्यापार वस्तु पर अधिक "व्यवसाय" व्यवहार जोड़ना है। ऐसा लगता है कि व्यापार वस्तु का सही ढंग से उपयोग नहीं किया जा रहा है। –

5

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

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

public class Product { 
    public int Id {get; set;} 
    public int CustomerId { get; set;} 
    public virtual Customer Customer { get; set;} 
} 
public class ProductLazyLoadProxy { 
    ICustomerRepository _customerRepository; 
    public ProductLazyLoadProxy(ICustomerRepository customerRepository) { 
    _customerRepository = customerRepository; 
    } 
    public override Customer { 
    get { 
     if(base.Customer == null) 
     Customer = _customerRepository.Get(CustomerId); 
     return base.Customer 
    } 
    set { base.Customer = value; } 
    } 
} 
public class ProductRepository : IProductRepository { 
    public Product Get(int id) { 
    var dr = GetDataReaderForId(id); 
    return new ProductLazyLoadProxy() { 
     Id = Convert.ToInt(dr["id"]), 
     CustomerId = Convert.ToInt(dr["customer_id"]), 
    } 
    } 
} 

लेकिन लगभग 20 इनमें से लेखन के बाद मैं सिर्फ लगाने और उन्हें विन्यास के लिए FluentNHibernate आजकल बाधाओं पहले से कहीं ज्यादा कम कर रहे हैं के लिए NHibernate छोड़ दिया और सीखा Linq2NHibernate साथ,।

2

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

उस तरफ, आप जिस पैटर्न का उपयोग कर रहे हैं वह एक रिपोजिटरी पैटर्न जैसा दिखता है। मैं कहूंगा कि आपके विकल्प

  • आपकी ईमेल कक्षा में एक सेवा ऑब्जेक्ट - ईमेल सेवा - कन्स्ट्रक्टर या संपत्ति में तत्काल। जैसे एक उदाहरण के माध्यम से एक्सेस किया गया email.Service.GetById (आईडी)
  • ईमेल पर एक स्थिर विधि, Email.GetById (आईडी) जो एक समान दृष्टिकोण
  • एक पूरी तरह से अलग स्थिर वर्ग मूल रूप से एक बहाना वर्ग है वह यह है कि जैसे, उदाहरण के लिए, ईमेलमैनेजर, जैसे ईमेलमैनेजर.GetById (int)
  • ActiveRecord पैटर्न जहां आप किसी उदाहरण से निपट रहे हैं, जैसे ईमेल। सेव() और ईमेल।GetById()
2

अधिकतर आपके एप्लिकेशन के पास transaction scripts में डोमेन लॉजिक सेटअप है। लेनदेन स्क्रिप्ट का उपयोग करने वाले .NET कार्यान्वयन के लिए मार्टिन फाउलर table data gateway पैटर्न के उपयोग की अनुशंसा करता है। .NET इस पैटर्न के लिए अच्छा समर्थन प्रदान करता है क्योंकि तालिका डेटा गेटवे पैटर्न record set के साथ बढ़िया है, जो माइक्रोसॉफ्ट अपने डेटासेट प्रकार के वर्गों के साथ लागू करता है।

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

यदि आपका व्यवसाय तर्क कुछ मान्यताओं की तुलना में अधिक जटिल है domain model एक अच्छा विकल्प बन जाता है। ध्यान दें कि एक डोमेन मॉडल डेटा एक्सेस आवश्यकताओं के एक अलग सेट के साथ आता है!

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