سؤال

لقد تم استكشاف BDD/DDD ونتيجة لذلك تحاول أن تصل مع التنفيذ السليم نمط مستودع.حتى الآن كان من الصعب التوصل إلى توافق في الآراء حول أفضل طريقة لتنفيذ هذا.لقد حاولت أن تغلي وصولا إلى الصيغ التالية, ولكن أنا متأكد من الذي هو أفضل نهج.

للإشارة أنا بناء ASP.MVC التطبيق مع NHibernate كما في نهاية العام.

public interface IRepository<T> {
        // 1) Thin facade over LINQ
        T GetById(int id);
        void Add(T entity);
        void Update(T entity);
        void Remove(T entity);
        IQueryable<T> Find();
        // or possibly even
        T Get(Expression<Func<T, bool>> query);
        List<T> Find(Expression<Func<T, bool>> query);
}

public interface IRepository<T> {
        // 2) Custom methods for each query
        T GetById(int id);
        void Add(T entity);
        void Update(T entity);
        void Remove(T entity);
        IList<T> FindAll();
        IList<T> FindBySku(string sku);
        IList<T> FindByName(string name);
        IList<T> FindByPrice(decimal price);
        // ... and so on
}

public interface IRepository<T> {
        // 3) Wrap NHibernate Criteria in Spec pattern
        void Add(T entity);
        void Update(T entity);
        void Remove(T entity);
        IList<T> FindAll();
        IList<T> FindBySpec(ISpecification<T> specification);
        T GetById(int id);
}


public interface IRepository<T> {
        // 4) Expose NHibernate Criteria directly
        T GetById(int id);
        void Add(T entity);
        void Update(T entity);
        void Remove(T entity);
        IList<T> FindAll();
        IList<T> Find(ICriteria criteria);
        // .. or possibly
        IList<T> Find(HQL stuff);
}

بلدي الأفكار الأولية التي

1) تعتبر كبيرة من وجهة نظر الكفاءة ، ولكن قد تحصل في ورطة الحصول على أشياء أكثر تعقيدا.

2) يبدو مملة جدا و يمكن في نهاية المطاف مع مزدحمة جدا الدرجة, لكن على خلاف ذلك يوفر درجة عالية من الفصل بين المجال المنطق طبقة البيانات التي أحب.

3) يبدو صعبا في الأمام و المزيد من العمل لكتابة الاستفسارات ، ولكن حدود التلوث فقط المواصفات طبقة.

4) بلدي المفضلة لديك على الأقل, ولكن ربما الأكثر مباشرة تنفيذ وربما الأكثر قاعدة بيانات فعالة على استعلامات معقدة ، على الرغم من أنه يضع الكثير من المسؤولية على رمز الدعوة.

هل كانت مفيدة؟

المحلول

وأعتقد أنها كلها خيارات جيدة (ربما باستثناء 4 إذا كنت لا تريد لادراك التعادل نفسك لnhibernate)، ويبدو أن لديها إيجابيات وسلبيات تحليلها جيدا لاتخاذ قرار بشأن بنفسك على أساس المسعى الحالي. لا تغلب نفسك <م> من من الصعب في هذا الشأن.

وأنا أعمل حاليا على مزيج ما بين 2 و 3 أعتقد:

public interface IRepository<T> 
{
        ...
        IList<T> FindAll();
        IList<T> FindBySpec(ISpecification<T> specification);
        T GetById(int id);
}

public interface ISpecificRepository : IRepository<Specific> 
{
        ...
        IList<Specific> FindBySku(string sku);
        IList<Specific> FindByName(string name);
        IList<Specific> FindByPrice(decimal price);
}

وهناك أيضا مستودع (من T) الفئة الأساسية.

نصائح أخرى

وهناك أيضا حجة جيدة ل"أي من أعلاه" النهج.

والمشكلة مع المستودعات العامة هي أن كنت صنع افتراض أن كل الكائنات في النظام الخاص بك سوف تدعم جميع عمليات الخام الرابعة: إنشاء، قراءة، تحديث، حذف. ولكن في الأنظمة المعقدة، فسوف المرجح أن يكون الكائنات التي تدعم سوى عدد قليل من العمليات. على سبيل المثال، قد يكون لديك الكائنات التي يتم أو الكائنات التي يتم إنشاؤها ولكن تحديثها أبدا للقراءة فقط.

هل يمكن كسر واجهة IRepository في واجهات صغيرة، لقراءة وحذف، وما إلى ذلك ولكن الذي يحصل فوضوي بسرعة كبيرة.

وغريغوري الشباب يجعل حجة جيدة (من / برنامج منظور طبقات DDD) أن كل مستودع يجب أن تدعم فقط العمليات التي هي محددة لكائن المجال أو تجميع كنت تعمل مع. وهنا مقاله على المستودعات العامة .

وعن وجهة نظر بديلة، انظر هذا Ayende <لأ href = "http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx" يختلط = " noreferrer "> بلوق وظيفة .

واحدة من الأشياء نقوم به هو أن جميع المستودعات لدينا الاحتياجات المختلفة لذلك نحن بصدد إنشاء مجموعة من واجهات:

public interface IReadOnlyRepository<T,V>
{
   V Find(T);
}

في هذا المثال للقراءة مستودع فقط لا يحصل فقط من قاعدة البيانات. سبب T، V V هو يمثل ما يتم إرجاعها من قبل مستودع وT يمثل ما يتم تمريرها في، لذلك يمكن أن تفعل شيئا مثل هذا:

public class CustomerRepository:IReadOnlyRepository<int, Customer>, IReadOnlyRepository<string, Customer>
{
    public Customer Find(int customerId)
    {
    }

    public Customer Find(string customerName)
    {
    }
}

ويمكنني أيضا أن إنشاء واجهات منفصلة لإضافة وتحديث وحذف. بهذه الطريقة إذا كان لي مستودع لا يحتاج السلوك بعد ذلك فقط لا يطبق الواجهة.

وأنا معجب BIF من 1 لأنني لا يمكن إنشاء الفلاتر وطرق الإرشاد الترحيل مما كنت يمكن أن تنطبق على IQueryable <> القيم مقابل أسلوب بحث. وأظل طرق الإرشاد في طبقة البيانات ثم بناء على الطاير في طبقة رجال الأعمال. (غير نقية تماما، باعتراف الجميع).

وبطبيعة الحال، عندما يستقر النظام لدي الخيار لجعل طرق بحث معينة باستخدام طرق الإرشاد نفسها وتحسين وظائفها باستخدام <>.

عند استخدام NH مع ينق المخزون الخاص بك يمكن أن يكون:

session.Linq<Entity>()

والمواصفات هي الأشياء التي تتناول ما يلي:

IQueryable<Entity>

ويمكنك اجهة كل ذلك بعيدا إذا كنت تريد، ولكن هذا هو الكثير من العمل الدنيوي لمجرد فكرة مجردة.

وبسيط هو جيد. ياه، NH يفعل قواعد البيانات، ولكنه يوفر الكثير من أكثر أنماط. وجود البعض من DAL تعتمد على NH أبعد ما يكون عن خطيئة.

وأعتقد أن ذلك يعتمد على الاحتياجات الخاصة بك. ومن المهم أن نفكر في مستودع بالتزامن مع أنماط التصميم الأخرى التي تنظر للاستخدام. وأخيرا، فإنه يعتمد جدا على ماذا تتوقع من مستودع (ما هي الأسباب الرئيسية لاستخدامه).

هل انت بحاجة الى خلق طبقة صارمة (على سبيل المثال سوف تحتاج إلى استبدال NHibernate مع الكيان الإطار في المستقبل)؟ هل تريد أن تكتب اختبار خاصة إلى أساليب مستودع؟

وليس هناك أفضل طريقة كيفية إنشاء مستودع. هناك فقط عدد قليل من الطرق، وأنها بالتأكيد متروك لكم، ما هو الأكثر عملية لاحتياجاتك.

تذبل مستودع

مادة ذات صلة من قبل جيمي Bogard من LosTechies

http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/09/10/wither-the-repository.aspx

أيضا أخرى سريعة المادة مع بعض التعليقات توحي الإصدار رقم 2 هو في الحقيقة دعاء نمط وليس مستودع.

http://fabiomaulo.blogspot.com/2009/06/linq-and-repository.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top