فصل 8 از 8 درس 5 از 6

جمع‌بندی حرفه‌ای

پروژه نهایی: سامانه سفارش و پرداخت

بخشی از آموزش جامع Design Patterns در C# و .NET

محتوای درس پروژه نهایی: سامانه سفارش و پرداخت

در این درس یک جنبه مهم از طراحی شیءگرا را با نگاه کاربردی بررسی می‌کنیم.

هدف یادگیری

  • بتوانید مفهوم «پروژه نهایی: سامانه سفارش و پرداخت» را با زبان خودتان توضیح دهید.
  • بتوانید مسئله‌ای را که این تکنیک حل می‌کند از روی کد تشخیص دهید.
  • بتوانید تشخیص دهید چه زمانی استفاده از آن اشتباه یا اضافه‌کاری است.

مسئله اصلی چیست؟

ارائه یک ورودی ساده روی مجموعه‌ای از زیرسیستم‌های پیچیده مسئله اصلی معمولاً زمانی شروع می‌شود که یک تصمیم طراحی در چند نقطه از سیستم تکرار می‌شود و هر تغییر، چند فایل و چند کلاس را درگیر می‌کند.

مدل ذهنی ساده

سناریوی ذهنی این درس: CheckoutFacade برای Inventory, Payment, Shipping, Notification. به جای اینکه Client همه جزئیات را بداند، یک مرز طراحی ایجاد می‌کنیم تا بخش متغیر پشت یک قرارداد یا ساختار مشخص قرار بگیرد.

پیاده‌سازی نمونه در C#

نمونه کد آموزشی

نمونه کد این درس در بخش کد درس قرار داده شده است.

کد قبل از Refactoring چه بویی می‌دهد؟

  • if/switch بزرگ که با هر نوع جدید رشد می‌کند.
  • ساخت مستقیم وابستگی‌ها با new در لایه Business/Application.
  • تکرار منطق cross-cutting مثل Logging، Retry یا Validation.

مراحل Refactoring

1. نقطه تغییر را مشخص کنید و دقیقاً بگویید کدام تصمیم ناپایدار است.

2. یک قرارداد کوچک و معنادار برای بخش متغیر تعریف کنید.

3. Concrete implementationها را پشت قرارداد منتقل کنید.

4. Client را فقط به قرارداد وابسته کنید.

5. با تست، رفتار قبل و بعد را یکسان نگه دارید و سپس پیچیدگی اضافی را حذف کنید.

چه زمانی استفاده کنیم؟

وقتی Client نباید جزئیات ترتیب و هماهنگی چند سرویس را بداند. اگر تنها یک پیاده‌سازی ساده دارید و احتمال تغییر واقعی کم است، Pattern ممکن است صرفاً تعداد فایل‌ها را زیاد کند.

نکته تخصصی این درس

در پروژه نهایی چند Pattern با هم کار می‌کنند، اما هرکدام مسئول یک مشکل مشخص‌اند: Strategy برای تخفیف، Adapter برای درگاه بانک، State برای چرخه سفارش، Facade برای Checkout و Observer برای رویدادها.

خطاهای رایج

  • استفاده از Pattern فقط چون معروف است، بدون مسئله مشخص.
  • ساخت interface برای هر کلاس حتی وقتی هیچ جایگزینی یا boundary وجود ندارد.
  • مخلوط کردن مسئولیت Pattern با Business Rule و ایجاد کلاس‌های همه‌کاره.

Best Practice

  • قرارداد را کوچک و بر اساس نیاز Client طراحی کنید.
  • نام کلاس‌ها را بر اساس نقش دامنه/کاربرد انتخاب کنید، نه صرفاً نام Pattern.
  • قبل از اضافه کردن abstraction یک تغییر واقعی یا تست‌پذیری لازم را نشان دهید.
  • برای سناریوهای async، cancellation و exception handling را بخشی از قرارداد در نظر بگیرید.

تمرین

  • مدل Order با Stateهای Draft/Paid/Shipped/Cancelled بسازید.
  • دو درگاه پرداخت را با Adapter پشت IPaymentGateway قرار دهید.
  • CheckoutFacade را ایجاد و OrderPlaced را به دو Observer ارسال کنید.
  • برای تخفیف Strategy و برای Queryهای مهم Repository تخصصی اضافه کنید.

جمع‌بندی

مهم‌ترین نکته این درس این است که «پروژه نهایی: سامانه سفارش و پرداخت» یک اسم برای کلاس‌بندی کد نیست؛ یک راه شناخته‌شده برای مدیریت یک نوع مشخص از تغییر است. اگر مسئله وجود دارد، Pattern کمک می‌کند نقطه تغییر محدود و قابل تست شود؛ اگر مسئله وجود ندارد، ساده‌ترین طراحی معمولاً بهتر است.

درس بعدی

درس 88 از 89 در آموزش جامع Design Patterns در C# و .NET

نمونه کد

public sealed class CheckoutFacade
{
 public async Task CheckoutAsync(Order order)
 {
 await _inventory.ReserveAsync(order);
 await _payment.PayAsync(order.Total);
 await _shipping.CreateShipmentAsync(order);
 await _notifier.SendAsync("Order confirmed");
 }
}

خروجی مورد انتظار

خروجی این درس شامل اجرای نمونه مرتبط با «پروژه نهایی: سامانه سفارش و پرداخت» و درک کاربرد آن در سناریوهای واقعی C# و .NET است.