Farzad Afi Logo

FarzadAfi

آموزش تخصصی برنامه نویسی

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

📖توضیحات درس

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

📄جزوه

مفاهیم کلیدی

  • Service Layer
    لایه‌ای که مسئول مدیریت منطق کسب‌وکار (Business Logic) برنامه است. این لایه به عنوان یک واسط بین لایه نمایش (UI) و لایه دسترسی به داده‌ها عمل کرده و تصمیم می‌گیرد که چه فرآیندهایی روی داده‌ها انجام شود.

  • Repository Layer
    لایه‌ای که وظیفه مستقیم آن تعامل با منبع داده (دیتابیس یا آرایه) است. این لایه عملیات‌های پایه مانند ذخیره‌سازی، جستجو و حذف داده‌ها را مدیریت می‌کند و از سایر بخش‌های برنامه مستقل است.

  • Model
    یک Class که ساختار و قالب داده‌های اصلی برنامه را تعریف می‌کند؛ برای مثال فیلدهای مربوط به یک کاربر مانند نام، نام کاربری و رمز عبور در این کلاس قرار می‌گیرند.

  • CRUD Operations
    مخفف Create (ایجاد)، Read (خواندن)، Update (بروزرسانی) و Delete (حذف) است که به چهار عملیات اصلی در مدیریت داده‌ها اشاره دارد.

  • Separation of Concerns
    یک اصل طراحی نرم‌افزار که بر تفکیک وظایف تأکید دارد. هر بخش از کد (مانند مدیریت ورودی، منطق محاسباتی و ذخیره‌سازی) باید در لایه مخصوص به خود قرار گیرد تا خوانایی و نگهداری برنامه آسان‌تر شود.

  • 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 می‌پرسد که آیا این نام کاربری تکراری است یا خیر؛ اگر تکراری نبود، دستور ذخیره را صادر می‌کند.
  4. لایه Menu: کلاس UserMenu ورودی‌ها را از کاربر می‌گیرد و بر اساس عدد وارد شده توسط کاربر، متدهای مربوطه در Service را فراخوانی می‌کند.

بیشتر بدانید

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

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

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

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