دليلك الشامل لفهم Generic Repository

  • ما هو Repository Pattern
  • لماذا نحتاج إلى Generic Repository
  • الفرق بين Repository التقليدي و Generic Repository

ما هو Repository Pattern

نمط المستودع ( Repository Pattern ) هو أسلوب يستخدم لتنظيم الكود عن طريق عزل طبقة الوصول للبيانات ( Data Access Layer ) عن الطبقة التي تحتوي منطق عمل المشروع ( Business Logic Layer ).

إذاً بدلاً من كتابة استعلامات قاعدة البيانات مباشرة في كل جزء من التطبيق، نقوم بإنشاء كلاس يُسمى Repository ليكون مسؤولاً عن تنفيذ العمليات الأساسية مثل إنشاء ( Create قراءة ( Read تحديث ( Update حذف ( Delete ) — و هي العمليات المعروفة بـمصطلح CRUD — على كيان ( Entity ) معين مثل المنتج Product أو المستخدم User.

هذا النمط يجعل الكود أنظف، أسهل في الصيانة، و يسهّل اختبار التطبيق و تطويره مستقبلاً.

لماذا نحتاج إلى Generic Repository

نحتاج إلى Generic Repository لتقليل التكرار و تبسيط التعامل مع البيانات في التطبيقات، خصوصاً عندما يكون لدينا كيانات ( Entities ) كثيرة مثل Product، User, Order إلخ.. فبدلاً من إنشاء Repository خاص لكيان و كتابة نفس عمليات CRUD (إضافة، قراءة، تعديل، حذف) مراراً و تكراراً، نقوم بإنشاء مستودع عام ( Generic Repository ) يستخدم النوع العام T ليقوم بنفس الوظائف لأي كيان نمرّره إليه.


أهم فوائده

  • إعادة استخدام الكود ( Code Reusability ) تكتب العمليات مرة واحدة و تستخدمها مع أي كيان.
  • تقليل التكرار لا حاجة لكتابة نفس المنطق أكثر من مرة، حيث يتم تطبيق مبدأ DRY ( Don't Repeat Yourself و هو أحد مبادئ التصميم البرمجي الجيدة.
  • توحيد طريقة التعامل مع البيانات كل الكيانات تتعامل مع نفس الإنترفيس ( Interface ) و بنفس الأسلوب.
  • سهولة التوسيع و الصيانة لو احتجت تعدل في طريقة الحذف أو الإضافة، تعدّلها في مكان واحد فقط.
  • تحسين الاختبارات ( Testability ) سهول استخدام كائنات وهمية ( Mocks ) لاختبار منطق التطبيق دون الحاجة إلى الاتصال بقاعدة البيانات.

الفرق بين Repository التقليدي و Generic Repository

الـ Repository التقليدي يعتمد على إنشاء كود خاص بكل كيان ( Entity ) في المشروع.
على سبيل المثال، إذا كان لديك كيان Product و كيان User فإنك ستقوم بإنشاء كلاسين منفصلين كما يلي.

مثال

public class ProductRepository {
    public Product GetById(int id) { ... }
    public void Add(Product product) { ... }
}

public class UserRepository {
    public User GetById(int id) { ... }
    public void Add(User user) { ... }
}

هذا الأسلوب يجعل قابلية إعادة الاستخدام منخفضة لأن المنطق نفسه يتم تكراره مع تغييرات بسيطة، مما يؤدي إلى تكرار مرتفع في الكود و صعوبة في الصيانة و التوسعة مستقبلاً.


أما في الـ Generic Repository فإنه بدلاً من إنشاء كلاس لكل كيان، ننشئ كلاس عام يستخدم النوع T كما يلي.

مثال

public class GenericRepository<T> where T : class {
    public T GetById(int id) { ... }
    public void Add(T entity) { ... }
}

بهذا الشكل، يمكنك استخدام نفس الكلاس مع أي كيان على النحو التالي.

مثال

var productRepo = new GenericRepository<Product>();
var userRepo = new GenericRepository<User>();

هذا الأسلوب يجعل الكود أقل، التكرار فيه أقل، و تنظيمه أفضل.


خلاصة

من حيث البساطة، النمط التقليدي Repository قد يكون مناسباً في المشاريع الصغيرة التي تحتوي على عدد محدود من الكيانات. لكن في المشاريع المتوسطة أو الكبيرة، يصبح Generic Repository أكثر فعالية لأنه يسهل التوسع، و أي تعديل يتم في مكان واحد ينعكس على كل الكيانات.

مثلاً، إذا أردت تعديل كيفية تنفيذ الدالة Add() فإنك ستحتاج إلى تعديلها في كل Repository تقليدي، بينما في Generic Repository تعدّلها مرة واحدة فقط داخل الكلاس العام.

آخر تحديث في 03-09-2025

ibrahim alomar

خريج من كلية الهندسة المعلوماتية، شغوف بتطوير البرمجيات وبرمجة تطبيقات الويب وأتمتع بمهارات قوية في حل المشكلات والخوارزميات، وسبق لي العمل على العديد من المشاريع البرمجية التي عززت من قدراتي التقنية والعملية وأسعى باستمرار للتعلم وتطوير نفسي .

تعليقات

لا يوجد أي تعليق بعد

أضف تعليق

يجب تسجيل الدخول حتى تتمكن من إضافة تعليق أو رد.