الگوی Repository در برنامه‌نویسی (Repository Pattern)

الگوی Repository، Repository Pattern، الگوهای طراحی، اصول طراحی نرم‌افزار، برنامه‌نویسی شیء‌گرا 1404/7/16
نویسنده: مدرس بهمن آبادی

الگوی Repository در برنامه‌نویسی (Repository Pattern)

الگو Repository

مقدمه

در طراحی نرم‌افزار، یکی از اصول مهم، جدا کردن لایه‌ها و مدیریت وابستگی‌ها است. وقتی پروژه بزرگ می‌شود، نیاز داریم کدها را طوری سازمان‌دهی کنیم که منطق تجاری (Business Logic) از جزئیات پایگاه داده جدا باشد.
الگوی Repository Pattern دقیقاً برای همین هدف به‌وجود آمده است.

تعریف Repository Pattern

Repository Pattern الگویی است برای جداسازی منطق دسترسی به داده‌ها (Data Access Logic) از منطق کسب‌وکار (Business Logic) در یک برنامه.

به زبان ساده:

  • لایه‌ی Repository مانند یک واسطه (Mediator) بین دیتابیس و کد برنامه عمل می‌کند.

  • برنامه‌نویس دیگر مستقیماً با Entity Framework، SQL، Dapper یا MongoDB کار نمی‌کند.

  • بلکه از طریق Repository، داده‌ها را می‌خواند یا می‌نویسد.

 

 هدف اصلی Repository Pattern

هدفتوضیح
جدا کردن لایه‌هامنطق داده از منطق تجاری جدا می‌شود.
تست‌پذیری بهترمی‌توان Repository را در تست‌ها Mock کرد.
انعطاف‌پذیری در برابر تغییر دیتابیساگر نوع پایگاه داده تغییر کند، فقط Repository باید تغییر کند.
کد تمیزتر و منظم‌ترمنطق ذخیره‌سازی و واکشی در یک محل متمرکز است.

ساختار کلی الگو

معمولاً Repository Pattern از ۳ بخش اصلی تشکیل می‌شود:

  1. Interface → مشخص می‌کند چه عملیات‌هایی باید وجود داشته باشند (مثل Get, Add, Remove).

  2. Concrete Repository → پیاده‌سازی واقعی عملیات‌ها (مثلاً با EF Core یا SQL).

  3. Service / Business Layer → از Repository استفاده می‌کند تا داده‌ها را مدیریت کند.

مثال کامل در C#

فرض کنیم یک موجودیت ساده به نام Student داریم:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

 تعریف Interface برای Repository

public interface IStudentRepository
{
    IEnumerable<Student> GetAll();
    Student GetById(int id);
    void Add(Student student);
    void Update(Student student);
    void Delete(int id);
}

 این Interface مشخص می‌کند که هر Repository مربوط به Student باید بتواند عملیات CRUD را انجام دهد.

 

 پیاده‌سازی Repository با Entity Framework

public class StudentRepository : IStudentRepository
{
    private readonly AppDbContext _context;

    public StudentRepository(AppDbContext context)
    {
        _context = context;
    }

    public IEnumerable<Student> GetAll()
    {
        return _context.Students.ToList();
    }

    public Student GetById(int id)
    {
        return _context.Students.Find(id);
    }

    public void Add(Student student)
    {
        _context.Students.Add(student);
        _context.SaveChanges();
    }

    public void Update(Student student)
    {
        _context.Students.Update(student);
        _context.SaveChanges();
    }

    public void Delete(int id)
    {
        var student = _context.Students.Find(id);
        if (student != null)
        {
            _context.Students.Remove(student);
            _context.SaveChanges();
        }
    }
}

 

 حالا تمام کدهای مربوط به دیتابیس در همین کلاس متمرکز است.

 

 استفاده از Repository در لایهٔ سرویس (Business Logic)

public class StudentService
{
    private readonly IStudentRepository _repository;

    public StudentService(IStudentRepository repository)
    {
        _repository = repository;
    }

    public void RegisterNewStudent(string name, int age)
    {
        if (age < 6)
            throw new Exception("سن دانش‌آموز باید بالای ۶ سال باشد.");

        var student = new Student { Name = name, Age = age };
        _repository.Add(student);
    }

    public IEnumerable<Student> GetAllStudents()
    {
        return _repository.GetAll();
    }
}
 اینجا سرویس فقط از Interface Repository استفاده می‌کند و هیچ اطلاعی از دیتابیس یا EF ندارد.

 

 استفاده در برنامه

class Program
{
    static void Main()
    {
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase("StudentsDb")
            .Options;

        var context = new AppDbContext(options);
        var repository = new StudentRepository(context);
        var service = new StudentService(repository);

        service.RegisterNewStudent("حمید", 20);
        service.RegisterNewStudent("مریم", 19);

        foreach (var s in service.GetAllStudents())
        {
            Console.WriteLine($"{s.Id} - {s.Name} ({s.Age})");
        }
    }
}

 

ترکیب با Unit of Work Pattern

در پروژه‌های بزرگ معمولاً Repository Pattern همراه با Unit of Work Pattern استفاده می‌شود.
Unit of Work نقش هماهنگ‌کننده دارد تا چند Repository در یک تراکنش (Transaction) با هم کار کنند.

مزایای Repository Pattern

مزیتتوضیح
کد تمیز و ساختارمندعملیات داده از منطق کسب‌وکار جدا می‌شود.
تست‌پذیری آسانمی‌توان Repository را Mock کرد.
تغییر آسان دیتابیسنیازی نیست Business Logic تغییر کند.
قابلیت استفاده مجددRepositoryها در قسمت‌های مختلف سیستم استفاده می‌شوند.

 

معایب احتمالی

مشکلتوضیح
پیچیدگی اضافیبرای پروژه‌های کوچک ممکن است بیش از حد باشد.
لایه‌های زیادگاهی کد زیاد و لایه‌های اضافی ایجاد می‌کند.
وابستگی به Interface زیادبرای تازه‌کارها ممکن است درک آن سخت‌تر باشد.

 

جمع‌بندی نهایی

الگو Repository و انواع الگوهای مختلف دیگر در دوره جامع برنامه‌نویسی وب مهندس بهمن آبادی آموزش داده شده است.

الگوی Repository یکی از پرکاربردترین و مهم‌ترین الگوهای معماری در دنیای برنامه‌نویسی شیءگرا است، مخصوصاً در .NET، Java، Python و Node.js.
این الگو باعث می‌شود:

  • سیستم ساختارمندتر، تست‌پذیرتر و مقیاس‌پذیرتر باشد.

  • توسعه‌دهنده بتواند با تمرکز بر منطق کسب‌وکار کار کند، نه با دیتابیس.