درود دوستان! می‌خوایم یکی از کاربردی‌ترین الگوها یعنی الگوی Decorator رو بررسی کنیم که با اون می‌تونیم به صورت داینامیک و در زمان Runtime به آبجکت‌ها ویژگی اضافه کنیم و رفتار او‌ن‌ها رو تغییر بدیم.

می‌خوایم یاد بگیریم که:

 

مشکل کجاست؟ 🤔

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

class SimpleRoom {
  getDescription() {
    return "Base room";
  }

  getPrice() {
    return 2.00;
  }
}

const order = new SimpleRoom();

حالا می‌خوایم برنامه رو توسعه بدیم و کاری کنیم که کاربر بتونه مشخص کنه سفارش چه ویژگی‌هایی داشته باشه (غذا، وای‌فای، استخر، منظره رو به دریا و ...). شاید راهی که به ذهنمون برسه این باشه که برای هر ویژگی، یک زیرکلاس از SimpleRoom بسازیم:

class RoomWithWifi { ... }
class RoomWithBreakfast { ... }
class RoomWithWifiAndBreakfast { ... }
class RoomWithExtraBedAndWifi { ... }
// ...

همونطور که می‌بینیم با اضافه کردن هر ویژگی، باید کلی زیرکلاس بسازیم که با این کار تعداد کلاس‌ها به صورت تصاعدی بالا میره، مدیریت اونها سخت میشه و بنابراین اصلاً راه منطقی به حساب نمیاد. باید بتونیم ویژگی‌ها رو در لحظه و طبق درخواست کاربر به همون آبجکت SimpleRoom اضافه کنیم. توی چنین شرایطی الگوی Decorator به کمک ما میاد 👋

 

الگوی Decorator چیه؟

این الگو به ما کمک می‌کنه تا به صورت داینامیک و در زمان اجرای کد (Run-time) ویژگی‌هایی رو به آبجکت‌ها اضافه کنیم، بدون اینکه نیاز باشه کلاس‌ها رو دستکاری کنیم و برای هر ویژگی زیرکلاس بسازیم. با این الگو می‌تونیم طبق درخواست کاربر، ویژگی‌ها رو لایه به لایه و مرحله به مرحله به یک آبجکت اضافه کنیم.

ساختاری که این الگو می‌سازه شبیه به استک (پشته هست):

WiFi(Breakfast(TV(<<Room>>)));

اون Room آبجکت اصلی و پایه‌ای ما هست که می‌خوایم به اون ویژگی اضافه کنیم و TV و ‌Breakfast و WiFi ویژگی‌هایی هستن که روی این آبجکت به‌ترتیب و لایه به لایه اعمال میشن. به هر یک از این ویژگی‌ها میگن Decorator. توی ادامه می‌خوایم چنین ساختاری رو پیاده‌سازی کنیم.

الگوی Decorator زیر مجموعه الگوهای Structural - الگوهایی که کمک می‌کنن تا آبجکت‌های موجود طوری با هم در تعامل باشن تا بتونیم ساختارهای بزرگتری طراحی کنیم - هست. به این الگو Wrapper هم گفته میشه و پیاده‌سازی خیلی راحتی داره.