2013-08-01 7 views
7

आदेश मेरा डेटाबेस में वस्तुओं के लिए पहुँच प्रदान करने के लिए, मैं एक इंटरफेस डिजाइन करने के लिए बनाई गई टीम के सभी सदस्यों के लिए यह (सरलीकृत उदाहरण) की तरह इस्तेमाल किया जा रहा:कैसे एक डेटाबेस इंटरफ़ेस

public interface IDatabase 
{ 
    ObservableCollection<Animal> Animals{ get; } 
} 

मैं नहीं था ' टी डेटाबेस संदर्भ या कुछ ओरेकल वस्तुओं (कैप्सूलीकरण) की तरह आंतरिक उपयोग करने के लिए टीम वास्तविक जीवन में और इकाई परीक्षण के लिए इस्तेमाल किया जा करना चाहते हैं ...

मैं दो विशिष्ट वर्गों को लागू किया:

public class TestDatabase : IDatabase 
{ } 

public class OracleDatabase : IDatabase 
{ } 

कुछ उपयोग के बाद टीम के सदस्यों को अधिक से अधिक कार्यों के लिए पूछ रहे हैं, और मैं मेरी इंटरफ़ेस करने के तरीकों को जोड़ने के लिए:

public interface IDatabase 
{ 
    ObservableCollection<Animal> Animals{ get; } 
    ObservableCollection<Animal> Animals(Gender gender); 
    ObservableCollection<Animal> Animals(Gender gender, Race race); 
} 

फ़िल्टरिंग और सॉर्टिंग सामान में से कुछ निश्चित रूप से, डेवलपर खुद के द्वारा किया जा सकता है, लेकिन यह डेटाबेस के अंदर बेहतर स्थित है।


मेरे समस्या अब है कि मेरे इंटरफेस विस्फोट है, यह और अधिक विशिष्ट कार्यों हो रही है हर दिन, यह स्थिर से दूर है और हर समय बदलता रहता है है।

क्या मेरा डिज़ाइन शुरुआत से ही गलत है?

कुछ विचार है कि इस मुद्दे को हल करने के लिए:

  1. सभी डेवलपर्स के लिए डेटाबेस संदर्भ वस्तु का पर्दाफाश (बुरा मुझे लगता है कि)
  2. एक समारोह है कि एक LINQ क्वेरी
+0

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

उत्तर

4

आप रिपोजिटरी/यूनिटऑफवर्क पैटर्न को फिर से शुरू करने की कोशिश कर रहे हैं और आप इसे सही नहीं कर रहे हैं।

एक सही दृष्टिकोण इस के करीब होगा:

// shared between repositories 
public interface IGenericRepository<T> 
{ 
    T CreateNew(); 

    void Delete(T item); 
    void Update(T item); 
    void Insert(T item); 

    IEnumerable<T> FindAll(); 
    T FindOne(int id); 
} 

// specific repositories 
public interface IAnimalRepository : IGenericRepository<Animal> 
{ 
    IEnumerable<Animal> FindByNumberOfLegs(int NumberOfLegs); 
    // ... anything specific follows 
} 

public interface IHumanRepository : IGenericRepository<Human> 
{ 
    IEnumerable<Human> FindByGender(Gender gender); 
    // ... specific repository logic follows 
} 

// unit of work - a service for clients 
public interface IUnitOfWork : IDisposable 
{ 
    IAnimalRepository AnimalRepository { get; } 
    IHumanRepository HumanRepository { get; } 
    // .. other repositories follow 

    void SaveChanges(); 
} 

इस तरह आपकी सेवा परत भंडार परत पर निर्भर करता है और आप इकाई परीक्षण के लिए उदाहरण के लिए आसानी से कार्यान्वयन के बीच स्विच कर सकते हैं। अपने ग्राहकों को

// example code 
using (IUnitOfWork uow = new YourImplementationOfUnitOfWork()) 
{ 
    var animals = uow.AnimalRepository.FindByNumberOfLegs(3); 

    var person = uow.HumanRepository.CreateNew(); 
    person.Name = "John"; 
    uow.HumanRepository.Insert(person); 

    uow.SaveChanges(); 
} 

बारे में आप तरीकों की संख्या को सीमित करने की योजना है, तो आप बस थोड़ा भंडार इंटरफ़ेस संशोधित कर सकते हैं:

// shared between repositories 
public interface IGenericRepository<T> 
{ 
    T CreateNew(); 

    void Delete(T item); 
    void Update(T item); 
    void Insert(T item); 

    IQueryable<T> Query { get; } 
} 

इस तरह अपने ग्राहकों को LINQ का उपयोग कर सकते हैं:

// example code 
using (IUnitOfWork uow = new YourImplementationOfUnitOfWork()) 
{ 
    var animals = uow.AnimalRepository.Query.Where(a => a.NumberOfLegs == 3); 

    var person = uow.HumanRepository.CreateNew(); 
    person.Name = "John"; 
    uow.HumanRepository.Insert(person); 

    uow.SaveChanges(); 
} 
2

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

+0

मुझे लगता है कि यह मेरी मूल समस्या को हल नहीं करता है, यह केवल इसे और अधिक सहनशील बनाता है। – nabulke

+0

मैं प्रोजेक्ट संरचना को देखे बिना आपके डिज़ाइन पर टिप्पणी नहीं कर सकता लेकिन मुझे लगता है कि आप कुछ प्रकार की डेटा परत में इंटरफेस के आधार पर कंक्रीट कक्षाओं को कार्यान्वित कर रहे हैं? यदि ऐसा है तो LINQ क्वेरी के साथ डेटाबेस संदर्भ या पैरामीटर का खुलासा करना एक अलग डीएल परत होने के कारण को अमान्य करने जा रहा है। यह चिंता के किसी भी अलगाव के बिना सभी के लिए एक स्वतंत्र होने के अंत हो जाएगा। – Damon

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