جلسه شماره 22رایگان

Service and Repository Pattern | الگوی سرویس و ریپازیتوری

01:06:08

توضیحات جلسه

🎥 این ویدیو قسمت بیست و دوم از بوت‌کمپ رایگان جاواست. 🏛️ الگوی سرویس و ریپازیتوری در جاوا (Service Repository Pattern) 📝 در این قسمت، وارد دنیای معماری نرم‌افزار می‌شویم و با یکی از مهم‌ترین الگوهای طراحی در برنامه‌نویسی سازمان‌یافته آشنا می‌شویم: الگوی سرویس و ریپازیتوری. ⚠️ ابتدا با بررسی یک مشکل رایج در ساختار پروژه‌ها شروع می‌کنیم؛ مشکلی که در صورت حل‌نشدن، به پیچیدگی و وابستگی شدید بین کلاس‌ها منجر می‌شود. سپس راه‌حلی حرفه‌ای و تمیز برای آن ارائه می‌دهیم: جداسازی لایه‌ها با استفاده از Service و Repository. 🛠️ در ادامه، دو تمرین عملی طراحی شده‌اند تا این الگو را به‌صورت کامل در عمل پیاده‌سازی کنیم و بفهمیم دقیقاً چطور این معماری باعث افزایش خوانایی، تست‌پذیری و مقیاس‌پذیری کد می‌شود. 💻 سورس‌کد این قسمت در گیت‌هاب: 🔗 github.com/farzadafi/ProgrammingByFarzadAfi/tree/master/src/n_layer 👥 گروه پرسش و پاسخ تلگرام: @programmingByFarzadAfi 💬 گروه پرسش و پاسخ بله: @programming_by_farzadafi ❓ هر سوالی داشتی، می‌تونی توی گروه بپرسی؛ من یا مربی‌های گروه پاسخگو هستیم 🎓 بوت‌کمپ رایگان جاوا – آموزش تمرین‌محور برای یادگیری عمیق و ورود به بازار کار.

جزوه و مستندات

مفاهیم کلیدی

  • Service Layer

لایه Service مسئول مدیریت منطق کسب‌وکار (Business Logic) برنامه است.

این لایه به‌عنوان واسط بین لایه نمایش (UI) و لایه دسترسی به داده‌ها عمل می‌کند و تصمیم می‌گیرد چه فرایندهایی روی داده‌ها اجرا شوند.

  • Repository Layer

لایه Repository وظیفه تعامل مستقیم با منبع داده را دارد؛ مثل Database یا یک آرایه (Array).

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

  • Model

Model معمولاً یک Class است که ساختار داده‌های اصلی برنامه را تعریف می‌کند.

برای مثال، فیلدهای مربوط به یک کاربر مانند name، username و password در این کلاس قرار می‌گیرند.

  • CRUD Operations

CRUD مخفف چهار عملیات اصلی مدیریت داده است: Create، Read، Update و Delete.

  • Separation of Concerns

Separation of Concerns یک اصل طراحی نرم‌افزار است که بر تفکیک مسئولیت‌ها تأکید دارد.

هر بخش از کد، مانند مدیریت ورودی، منطق محاسباتی و ذخیره‌سازی، باید در لایه مخصوص خود قرار بگیرد تا خوانایی و نگهداری پروژه ساده‌تر شود.

  • Refactoring

Refactoring فرایند بازنویسی و اصلاح کد برای بهبود ساختار داخلی است، بدون اینکه رفتار بیرونی برنامه تغییر کند.

نکات مهم مصاحبه‌ای

  • چرا استفاده از الگوی Service-Repository اهمیت دارد؟

این الگو باعث جداسازی مسئولیت‌ها می‌شود.

اگر ورودی کاربر، منطق برنامه و اتصال به دیتابیس همگی داخل کلاس Main نوشته شوند، با بزرگ‌تر شدن پروژه نگهداری و توسعه دشوار می‌شود و احتمال خطا بالا می‌رود.

  • تفاوت اصلی لایه Service و Repository چیست؟

لایه Repository فقط با داده خام سروکار دارد؛ مثلاً جستجوی یک نام در یک لیست.

اما لایه Service منطق برنامه را پیاده‌سازی می‌کند؛ مثلاً بررسی می‌کند آیا رمز عبور واردشده با رمز عبور ذخیره‌شده مطابقت دارد یا خیر.

  • منظور از لایه Menu یا Controller در برنامه‌های کنسولی چیست؟

این لایه مسئول تعامل با کاربر است؛ ورودی‌ها را با Scanner دریافت می‌کند و خروجی را در کنسول چاپ می‌کند.

این لایه نباید مستقیماً درگیر منطق دیتابیس یا جزئیات ذخیره‌سازی داده شود.

  • چگونه می‌توان از بروز NullPointerException در جستجوی داده‌ها جلوگیری کرد؟

قبل از فراخوانی هر متد روی یک شیء، مانند equals، داخل حلقه باید بررسی کنید که مقدار آن خانه از آرایه null نباشد.

مثال یا سناریوی کاربردی

در این سناریو، یک سیستم ثبت‌نام (Sign Up) و ورود (Sign In) به‌صورت لایه‌بندی‌شده پیاده‌سازی می‌شود:

  1. لایه Model: کلاس User شامل فیلدهای name، username و password تعریف می‌شود.
  2. لایه Repository: کلاس UserRepository مسئول مدیریت آرایه کاربران است. متدهایی مانند save برای افزودن کاربر جدید و findByUsername برای جستجو در آرایه در این لایه قرار می‌گیرند.
  3. لایه Service: کلاس UserService منطق برنامه را پیاده می‌کند. مثلاً در متد ثبت‌نام، ابتدا از Repository بررسی می‌کند آیا username تکراری است یا خیر؛ اگر تکراری نبود، دستور ذخیره‌سازی را صادر می‌کند.
  4. لایه Menu: کلاس UserMenu ورودی‌ها را از کاربر می‌گیرد و بر اساس عدد واردشده، متدهای مربوط در Service را فراخوانی می‌کند.

بیشتر بدانید

  • نکته IDE: برای تغییر نام یک متد یا کلاس در کل پروژه به‌صورت خودکار، در IntelliJ از میان‌بر Shift + F6 استفاده کنید (Refactor Rename).

  • نکته کدنویسی: در برنامه‌های کنسولی، بعد از گرفتن مقدار عددی با nextInt()، معمولاً لازم است یک بار nextLine() خالی فراخوانی شود تا مشکل جا ماندن ورودی‌های بعدی برطرف شود.

  • توسعه‌پذیری: اگرچه در این آموزش از آرایه برای ذخیره‌سازی استفاده شده است، اما با این معماری اگر در آینده بخواهید از دیتابیس واقعی مثل PostgreSQL استفاده کنید، کافی است کدهای لایه Repository را تغییر دهید و سایر لایه‌ها بدون تغییر باقی می‌مانند.

  • دنیای واقعی: امروزه برنامه‌های کنسولی کمتر استفاده می‌شوند و بیشتر سیستم‌ها تحت وب هستند، اما درک این لایه‌بندی، پایه و اساس فریم‌ورک‌های بزرگی مثل Spring در جاوا است.