حوزه: Object
هدف: Structural
نقش الگو
GOF(Gang of Four) این الگو را به این شکل تعریف کردهاند که "با استفاده از Builder Pattern، ساختار (construction) اشیاء پیچیده را از نمایش (representation) آن جدا میکنیم. بنابراین میتوان با یک فرایند ساخت، چند نمایش مختلف ایجاد کرد ". همانطور که از نام آن مشخص است، از این الگو برای ساخت اشیاء به صورت جزء به جزء یا به عبارت دیگر مرحله به مرحله استفاده میشود. منطق پیچیده ساخت شی از client جدا شده است و client با ارسال مجموعهای از جزئیات، شی و اطلاعات مورد نیاز را بدست می آورد.
الگوی Builder از چهار جزء زیر تشکیل میشود:
- Product
- Builder
- Concrete Builder
- Director
برای درک بهتر ادامه توضیحات را با یک مثال پیش میبریم.
فرض کنید از شما خواسته شده است تا نحوهی ساخت تلفن همراه را پیاده سازی نمایید. شما در گام اول 2 نوع تلفن همراه را شناسایی نمودهاید (Android و Windows Phone). پس از شناسایی، احتمالا هر کدام از این انواع را یک کلاس در نظر میگیرید و به کمک یک واسط یا کلاس انتزاعی، شروع به ساخت کلاس مینمایید، تا در آینده اگر تلفن همراه جدیدی شناسایی شد، راحتتر بتوان آن را در پیاده سازی دخیل نمود. اگر چنین فکر کرده اید باید گفت که 90% با الگوی طراحی Builder آشنا هستید و از آن نیز استفاده میکنید، بدون اینکه متوجه باشید از این الگو استفاده کردهاید. در کدهای زیر این الگو را قدم به قدم بررسی خواهیم نمود.
قدم 1: تلفن همراه چه بخشهایی میتواند داشته باشد؟ (برای مثال یک OS دارند، یک Name دارند و یک Screen) همچنین برای اینکه تلفن همراهی بتواند ساخته شود ابتدا بایستی نام آنرا بدانیم. کدهای زیر همین رویه را تصدیق مینمایند:
public class Product {
private String name;
private String screen;
private String os;
public Product(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen = screen;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
@Override
public String toString() {
return "Product{" +
"name='" + name + '\'' +
", screen='" + screen + '\'' +
", os='" + os + '\'' +
'}';
}
}
یک کلاس ساختهایم و نام آن را Product گذاشتیم. بخشهای مختلفی را نیز در آن تعریف نمودهایم. تابع ToString را برای استفادههای بعدی override کردهایم.
قدم 2: برای ساخت تلفن همراه چه کارهایی باید انجام شود؟ (برای مثال بایستی OS روی آن نصب شود، Screen آن مشخص شود. همچنین بایستی به طریقی بتوانم تلفن همراه ساخته شدهی خود را نیز پیدا کنم). کدهای زیر همین رویه را تصدیق مینمایند:
public interface IBuilder {
void BuildScreen();
void BuildOS();
Product getProduct();
}
یک واسط تعریف کردهایم تا به کمک آن هر تلفن همراهی را که خواستیم بسازیم.
قدم 3: از آنجا که فقط دو نوع تلفن همراه را فعلا شناسایی کردهایم (Android و Windows Phone) نیاز داریم تا این دو تا را بسازیم.
ابتدا تلفن همراه Android را میسازیم:
public class ConcreteBuilder1 implements IBuilder {
Product product;
public ConcreteBuilder1() {
product = new Product("Android Cell Phone");
}
public void BuildScreen() {
product.setScreen("Touch Screen 16 Inch.");
}
public void BuildOS() {
product.setOs("Android 4.4");
}
public Product getProduct() {
return product;
}
}
سپس تلفن همراه Windows Phone را میسازیم:
public class ConcreteBuilder2 implements IBuilder {
Product product;
public ConcreteBuilder2 () {
product = new Product("Windows Phone");
}
public void BuildScreen() {
product.setScreen("Touch Screen 32 Inch.");
}
public void BuildOS() {
product.setOs("Windows Phone 2014");
}
public Product getProduct() {
return product;
}
}
قدم 4: اول باید OS نصب شود یا Screen مشخص شود؟ برای اینکه توالی کار را مشخص سازم نیاز به یک کلاس دیگر دارم تا اینکار را انجام دهد:
public class Director {
public void construct(IBuilder builder) {
builder.BuildScreen();
builder.BuildOS();
}
}
این کلاس در متد Construct خود یک ورودی از نوع IBuilder میگیرد و براساس توالی مورد نظر، شروع به ساخت آن میکند.
قدم 5: نهایتا میخواهم به برنامهی خود بگویم که تلفن همراه Android را بسازد:
public class App {
public static void main(String[] args) {
Director director = new Director();
ConcreteBuilder1 creteBuilder1 = new ConcreteBuilder1();
director.construct(creteBuilder1);
System.out.println(creteBuilder1.getProduct().toString());
}
}
و به این صورت تلفن همراه من آماده است!
متد ToString در اینجا، همان ToString ابتدای بحث است که آن را Override کردیم.
به این نکته توجه کنید که اگر یک تلفن همراه جدید شناسایی شود، چه مقدار تغییری در کدها نیاز دارید؟ برای مثال تلفن همراه BlackBerry شناسایی شدهاست. تنها کاری که لازم است این است که یک کلاس بصورت زیر ساخته شود:
public class BlackBerry implements IBuilder {
private Product product;
public BlackBerry() {
this.product = new Product("BlackBerry");
}
public void BuildScreen() {
product.setScreen("Touch Screen 8 Inch.");
}
public void BuildOS() {
product.setOs("BlackBerry xyz");
}
public Product getProduct() {
return null;
}
}
مثال پیاده سازی شده با زبان جاوا را میتوانید از github من دانلود کنید.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.