پارسا پناهپور
پارسا پناهپور
خواندن ۵ دقیقه·۲ ماه پیش

الگوی Repository چیست ؟

ابتدا، ما تعریف الگوی Repository را از این کتاب با هم مرور خواهیم کرد:

Mediates between the domain and data mapping layers, acting like an in-memory collection of domain objects.
الگوی ریپوزیتوری چیست ؟
الگوی ریپوزیتوری چیست ؟




این تعریف بیان می‌کند که Repositor در واقع collection ازEntities است که به عنوان واسطی بین Data Mappers عمل می‌کند.

گفتیم که Repository مجموعه‌ای از Entities است، بنابراین باید متدهایی که یک مجموعه دارد را نیز شامل شود، متدهایی مانند:

  • add
  • remove
  • get
  • find

اولین نکته‌ای که باید به آن توجه کنیم این است که ما در حال صحبت درباره یک collection هستیم، بنابراین متدهایی مانند save (ذخیره) یا update (به‌روزرسانی) نداریم.

خب! اگر متدهای ذخیره و به‌روزرسانی نداریم، چطور می‌توانیم یک record جدید ایجاد کنیم یا آن را به‌روزرسانی کنیم؟ پاسخ این سوال را زمانی که به الگوی واحد کار (Unit of Work) اشاره کنیم، خواهیم داد.

گفتیم که هر Repository نمایانگر یک Entity است و مانند یک collection از آن Entity در حافظه عمل می‌کند. همچنین گفتیم که هر Repository به دلیل ویژگی collection بودن، دارای متدهایی مانند add ، remove ، get و find است. حالا، از آنجا که همه Repository ها باید این متدها را داشته باشند، برای جلوگیری از تکرار کد، یک کلاس پایه ایجاد می‌کنیم که این متدهای اساسی را دارد و سایر کلاس‌ها از آن ارث‌بری می‌کنند.

حالا اجازه دهید به یکی از مزایای Repository Pattern اشاره کنیم:

  • جلوگیری از تکرار کد.
  • کمک به تست‌پذیر بودن کد.
  • استقلال برنامه از پایگاه داده‌ها و ORMها.

در برنامه‌هایی که منطق کسب‌وکار به طور مستقیم به داده‌ها دسترسی دارد، ممکن است با مشکلات زیر مواجه شوید:

  • تکرار کد
  • افزایش پتانسیل خطاهای برنامه‌نویسی
  • دشواری در متمرکز کردن سیاست‌های مرتبط با داده‌ها، مانند کشینگ (Caching)
  • عدم توانایی در تست منطق کسب‌وکار به صورت جداگانه از وابستگی‌های خارجی

مخازن یا Repository ها کلاس‌هایی هستند که منطق لازم برای ذخیره یا بازیابی داده‌ها را پنهان می‌کنند. بنابراین، برنامه ما اهمیتی نمی‌دهد که از چه نوع ORM استفاده می‌کنیم، زیرا همه چیز مرتبط با ORM در لایه مخزن مدیریت می‌شود. Repository ها کلاس‌ها یا اجزایی هستند که منطق مورد نیاز برای دسترسی به منابع داده را در خود دارند. آن‌ها عملکردهای عمومی دسترسی به داده‌ها را متمرکز کرده و باعث بهبود قابلیت نگهداری می‌شوند و همچنین زیرساخت یا فناوری مورد استفاده برای دسترسی به پایگاه داده‌ها را از لایه Domain Model جدا می‌کنند.

از آنجایی که Domain نباید به فناوری وابسته باشد!درنتیجه نباید به لایه دسترسی به داده‌ها یا EF Core یا... ارجاع داشته باشد. دامنه فقط مجموعه‌ای از اینترفیس‌ها را تعریف می‌کند که بعداً به عنوان لایه Data Access شناخته می‌شوند و این اینترفیس‌ها باید پیاده‌سازی شوند!

معماری باید از فریمورک‌ها مستقل باشد. (رابرت سیسیل مارتین)

ممکن است مواردی پیش بیاید که نیاز به استفاده از چندین ORM در یک راه‌حل داشته باشید. احتمالاً از Dapper برای خواندن داده و از EFCore برای نوشتن داده استفاده کنید. این کار صرفاً برای بهینه‌سازی عملکرد است.

الگوی Repository به ما کمک می‌کند با ایجاد یک لایه انتزاعی در بالای لایه دسترسی به داده‌ها به این هدف برسیم. اکنون دیگر نیازی نیست که برنامه شما به EFCore یا هر ORM دیگری وابسته باشد. به جای اینکه EFCore تنها گزینه شما برای دسترسی به داده‌ها باشد، تبدیل به یکی از گزینه‌هایتان می‌شود.

حال که لایه EFCore خود را پیکربندی کرده‌ایم، بیایید کمی درباره روش سنتی دریافت داده‌ها از این لایه صحبت کنیم. به‌طور سنتی، شما مستقیماً از شیء dbContext برای خواندن و نوشتن داده‌ها استفاده می‌کنید. این روش خوب است، اما آیا برای بلندمدت واقعاً ایده‌آل است؟ وقتی مستقیماً از dbContext استفاده می‌کنید، در واقع Entity Framework Core را به شدت با برنامه خود وابسته می‌کنید. بنابراین، در آینده زمانی که فناوری جدیدتر و بهتری از EFCore منتشر شود یا نیاز باشد، تغییرات لازم برای پیاده‌سازی این فناوری جدید بسیار آزاردهنده خواهد بود، درست است؟

از یک طرف، حامیان الگوی Repository معتقدند که تمام کدهای دسترسی به پایگاه داده باید در Repository قرار گیرد، و از طرف دیگر، کسانی که با DbSet و EF کار می‌کنند، اعتراف می‌کنند که DbSet خود یک Repository است، بنابراین نیازی به ایجاد یک Repository دیگر نیست.

هر دو نوع تفکر تا حدی صحیح هستند. الگوی Repository و ایده پشت آن برای کار با پایگاه داده‌ها مفید است، اما این الگو مدت‌ها قبل از معرفی ORM‌هایی مانند EF شکل گرفته است و امروزه، با وجود ORM‌های قدرتمندی مثل EF، ممکن است استفاده از این الگو چندان مفید نباشد.

مهم‌ترین دلایلی که ممکن است بخواهید این کار را انجام دهید (اضافه کردن یک لایه انتزاعی در بالای DbContext):

  • شاید نمی‌خواهید پروژه‌تان کاملاً به Entity Framework و معماری آن وابسته باشد. بنابراین، Entity Framework را پشت این انتزاعات پنهان می‌کنید تا بتوانید آن را با هر ORM دیگری بدون هیچ تغییری در اینترفیس لایه دسترسی به داده‌ها جایگزین کنید.
  • پیاده‌سازی Repository سفارشی در هنگام پیاده‌سازی میکروسرویس‌ها یا برنامه‌های پیچیده‌تر چندین مزیت ارائه می‌دهد. الگوهای Unit of Work و Repository برای محصور کردن لایه persistence در نظر گرفته می‌شوند، به‌طوری‌که از لایه‌های برنامه و مدل دامنه جدا می‌شوند.
  • شما از Repository برای تعیین عملیات مجاز روی موجودیت‌های خاص استفاده می‌کنید.
  • خود مایکروسافت توصیه می‌کند که در سناریوهای پیچیده از الگوهای Repository استفاده کنید تا وابستگی را کاهش داده و قابلیت تست‌پذیری را بهبود ببخشید. در مواردی که می‌خواهید ساده‌ترین کد ممکن را داشته باشید، بهتر است از الگوی Repository اجتناب کنید.

    اگر به الگوی unit of work علاقه دارید میتونید دیدگاه های مختلف و نظرات پیرامون این الگو رو در مقاله ی من مطالعه کنید . برای خواندن کلیک کنید .
الگوی repositoryrepository patternclean codeclean architectureorm
Backend developer | .Net developer
شاید از این پست‌ها خوشتان بیاید