84- آموزش جاوااسکریپت | آموزش Factory Pattern
در این بخش با Factory Pattern در JavaScript آشنا میشویم؛ الگویی برای ساخت آبجکتهای مختلف با ویژگیهای مشترک. همچنین با یک مثال عملی، نحوه ساخت انواع عضویت با استفاده از Factory Method را بررسی میکنیم.
در این بخش، الگوی Factory Pattern یا Factory Method را در JavaScript بررسی میکنیم. این الگو روشی برای ساخت آبجکتها ارائه میدهد، بهخصوص زمانی که چند نوع آبجکت مختلف داریم که با وجود تفاوتها، ویژگیها و رفتارهای مشترکی هم دارند.
Factory Pattern زمانی بسیار کاربردی است که بخواهیم مجموعهای از آبجکتهای مشابه اما با نوعهای متفاوت را ایجاد، مدیریت و نگهداری کنیم.
Factory Pattern چیست؟
Factory Pattern الگویی برای ساخت آبجکتهاست. بهجای اینکه در بخشهای مختلف برنامه مستقیماً از new برای ساخت آبجکتها استفاده کنیم، یک لایه میانی میسازیم که مسئول ایجاد آبجکت مناسب بر اساس نوع موردنظر است.
این کار چند مزیت مهم دارد:
- منطق ساخت آبجکتها در یک نقطه متمرکز میشود.
- توسعه و نگهداری کد آسانتر میشود.
- اضافه کردن نوعهای جدید بدون تغییر گسترده در کل برنامه انجام میشود.
- کد خواناتر و ساختاریافتهتر خواهد شد.
یک مثال کاربردی
فرض کنید یک سامانه عضویت یا اشتراک داریم. اعضا میتوانند نوعهای مختلفی از عضویت داشته باشند، مانند:
- عضویت
simple - عضویت
standard - عضویت
super
هرکدام از این عضویتها ممکن است قیمت متفاوتی داشته باشند، اما در عین حال همگی ویژگیهای مشترکی مانند نام کاربر، نوع عضویت و هزینه را شامل میشوند.
در چنین شرایطی، Factory Pattern انتخاب مناسبی است.
ساخت Factory
ابتدا یک سازنده برای Factory تعریف میکنیم که وظیفه آن ایجاد عضو جدید بر اساس نوع عضویت است:
function MemberFactory() {
this.createMember = function (name, type) {
let member;
if (type === 'simple') {
member = new SimpleMembership(name);
} else if (type === 'standard') {
member = new StandardMembership(name);
} else if (type === 'super') {
member = new SuperMembership(name);
}
member.type = type;
member.define = function () {
console.log(`${this.name} (${this.type}): $${this.cost}`);
};
return member;
};
}
این کد چه کاری انجام میدهد؟
در متد createMember دو ورودی دریافت میشود:
nameبرای نام عضوtypeبرای نوع عضویت
سپس با توجه به مقدار type، یکی از کلاسها یا سازندههای مربوط به عضویت ساخته میشود. بعد از آن، ویژگی type و متد define به آبجکت اضافه میشود و در نهایت همان آبجکت برگردانده میشود.
تعریف انواع عضویت
اکنون باید سازندههای مربوط به هر نوع عضویت را تعریف کنیم:
function SimpleMembership(name) {
this.name = name;
this.cost = 5;
}
function StandardMembership(name) {
this.name = name;
this.cost = 15;
}
function SuperMembership(name) {
this.name = name;
this.cost = 25;
}
در این مثال:
- عضویت
simpleهزینه5دارد - عضویت
standardهزینه15دارد - عضویت
superهزینه25دارد
استفاده از Factory
حالا میتوانیم Factory را بسازیم و اعضای مختلف را با آن ایجاد کنیم:
const members = [];
const factory = new MemberFactory();
members.push(factory.createMember('John Doe', 'simple'));
members.push(factory.createMember('Chris Jackson', 'super'));
members.push(factory.createMember('Janice Williams', 'simple'));
members.push(factory.createMember('Tom Smith', 'standard'));
در اینجا، بدون اینکه مستقیماً سازندهی هر نوع عضویت را در بخشهای مختلف برنامه صدا بزنیم، فقط از Factory استفاده میکنیم.
نمایش اطلاعات اعضا
برای نمایش مشخصات هر عضو، میتوانیم روی آرایهی اعضا پیمایش انجام دهیم و متد define را اجرا کنیم:
members.forEach(function (member) {
member.define();
});
خروجی بهصورت مفهومی چیزی شبیه به این خواهد بود:
John Doe (simple): $5
Chris Jackson (super): $25
Janice Williams (simple): $5
Tom Smith (standard): $15
نسخه کامل مثال
در ادامه، کل کد را یکجا میبینید:
function MemberFactory() {
this.createMember = function (name, type) {
let member;
if (type === 'simple') {
member = new SimpleMembership(name);
} else if (type === 'standard') {
member = new StandardMembership(name);
} else if (type === 'super') {
member = new SuperMembership(name);
}
member.type = type;
member.define = function () {
console.log(`${this.name} (${this.type}): $${this.cost}`);
};
return member;
};
}
function SimpleMembership(name) {
this.name = name;
this.cost = 5;
}
function StandardMembership(name) {
this.name = name;
this.cost = 15;
}
function SuperMembership(name) {
this.name = name;
this.cost = 25;
}
const members = [];
const factory = new MemberFactory();
members.push(factory.createMember('John Doe', 'simple'));
members.push(factory.createMember('Chris Jackson', 'super'));
members.push(factory.createMember('Janice Williams', 'simple'));
members.push(factory.createMember('Tom Smith', 'standard'));
members.forEach(function (member) {
member.define();
});
چرا Factory Pattern مفید است؟
این الگو زمانی ارزشمند میشود که با آبجکتهای مختلفی سروکار داشته باشیم که:
- از یک ساختار کلی پیروی میکنند
- رفتارهای مشابهی دارند
- فقط در برخی ویژگیها یا مقدارها با هم فرق میکنند
در مثال این بخش، همهی آبجکتها «عضو» هستند، اما نوع عضویت و هزینهی آنها متفاوت است.
مزایای Factory Pattern
مهمترین مزایای این الگو عبارتاند از:
- کاهش تکرار در منطق ساخت آبجکتها
- جدا شدن منطق ایجاد آبجکت از منطق استفاده از آن
- امکان گسترش راحتتر برنامه
- افزایش خوانایی و نظم کد
جمعبندی
در این بخش با Factory Pattern در JavaScript آشنا شدیم. این الگو برای ساخت آبجکتهای متفاوت اما همخانواده بسیار مناسب است.
در مثال عملی این آموزش دیدیم که چگونه میتوان با یک Factory، انواع مختلف عضویت را ایجاد کرد و بدون درگیر شدن با جزئیات ساخت هر آبجکت، تنها بر اساس نوع موردنظر عضو جدید ساخت.
اگر در پروژهای با چند نوع آبجکت دارای ویژگیهای مشترک سروکار دارید، Factory Pattern میتواند یکی از بهترین انتخابها برای ساختاردهی کد باشد.