درود دوستان 🖐️ توی برنامه بارها شرایطی پیش میاد که می‌خوایم چند نمونه از یک کلاس داشته باشیم. شاید چیزی که به ذهنمون برسه این باشه که برای هر نمونه از کلمه کلیدی new استفاده کنیم:

class Cat {
  
}

const obj1 = new Cat();
const obj2 = new Cat();
const obj3 = new Cat();

اما گاهی ساختن نمونه به همین سادگی نیست و استفاده از new توی شرایط زیر بهینه نخواهد بود:

۱. ساختن نمونه از کلاس هزینه زیادی داره

مثلاً با هر new کردن از کلاس، اطلاعات زیادی باید از دیتابیس خونده و دسته‌بندی بشه:

class Post {
  constructor() {
    this.tags = db.tags.fetchAll();
  }
}

 

۲. آماده‌سازی نمونه زمان‌بر هست

مثلاً کلاسی داریم که نمونه‌های اون نیاز به پیکربندی‌های زیادی دارن:

class Car {
  public setWheels() {}
  public setDoors() {}
  public setWindows() {}
  public setSeats() {}
}

const car1 = new Car();
car1.setWheels();
car1.setDoors();
car1.setWindows();
car1.setSeats();

const car2 = new Car();
car2.setWheels();
car2.setDoors();
car2.setWindows();
car2.setSeats();

 

۳. کلاس واقعی برای ساختن نمونه ناشناخته هست

اگه از Dependency Injection استفاده می‌کنیم، کاملاً رایج هست که توی پارامترها از اینترفیسِ اون کلاس استفاده کنیم:

interface Animal {}

function produce(animal: Animal) {
  new Animal(); // Error: Cannot instantiate interface Animal
}

پس اینجا کلاس واقعی در دسترس نیست و نمی‌تونیم از اون نمونه‌ای بسازیم. توی چنین شرایطی راه حلی که به نظر مناسب میاد اینه که از خود پارامتر animal یک کپی بسازیم. برای این کار باید روی همه پراپرتی‌های آبجکت اصلی پیمایش کنیم و مقدارهای اونها رو به آبجکت جدید نسبت بدیم. ولی اگه آبجکت اصلی پراپرتی‌های private داشته باشه این کار ممکن نیست.
اینجاست که الگوی Prototype برای حل چنین مشکلاتی به کار ما میاد 👌

 

الگوی Prototype چیه؟

الگوی Prototype به ما این امکان رو میده تا با Clone (کپی) کردن از نمونه‌های موجود، نمونه‌های جدیدی بسازیم.

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