-
Notifications
You must be signed in to change notification settings - Fork 26
Home
- Encapsulate what varies.
دیاگرامهای کتاب Gang of for بر مبنای OMT هست: Object-modeling technique
#الگوی طراحی Builder
تعریف: الگوی طراحی Builder، روند ساخت یک شیء پیچیده را از نمایش آن جدا میکند به طوری که یک روند ساخت مشترک میتواند برای ساخت انوع نمایشها به کار گرفته شود.
مثال: فرض کنید بخواهیم انواع و اقسام خانهها را طراح کنیم. روند طراحی در تمامی خانهها یکسان است. که به کلاسهای زیر تقسیم میشود:
##Builder
- زیربنای آن را ایجاد میکنیم.
- ساختار و اسکلت آن را ایجاد میکنیم.
- سقف آن را میسازیم.
- فضای داخل خانه را طراحی میکنیم.
بنابراین برای طراحی همهٔ ساختمانها یک رویهٔ یکسان داریم. بنابراین یک کلاس اینترفیس برای تمامی ساختمانها با ۴ رویهٔ مذکور ایجاد میکنیم. که به آن Builder میگوییم.
در این مثال: HouseBuilder
حال به تعداد انواع خانهها، اینترفیس Builder را پیادهسازی میکنم، در این مثال میتوانیم خانهٔ خشتی، خانهٔ گلی، خانهٔ برفی، خانهٔ فلزی، خانهٔ فلزی، خانهٔ چوبی، خانهٔ سیمانی را بسازیم. به هر یک از این کلاسها ConcreateBuilder میگوییم:
- KheshtiBuilder
- GeliBuilder
- BarfiBuilder
- FeleziBuiler
پیمانکار ساختمان، ساختمانها را از طریق اینترفیس House ایجاد میکند. (ورودی: یک نوع خانه از نوع HouseBuilder)
- ساخت زیربنا
- ساخت اسکلت و ساختار ساختمان
- ساخت سقف
- طراحی درون ساختمان
محصول نهایی، حاصل ترکیب تمامی مراحل ساخت یک خانه است.
- خانهٔ گلی
- خانهٔ خشتی
- خانهٔ سیمانی و ...
HouseBuilder builder = new KheshtiBuilder(); Director director = new Director(builder); director.construct();
بیشتر بخوانید:
- Simple Factory (idiom)
- Factory Method Pattern
- Abstract Factory
نکات:
- Factories are used to encapsulate instantiation.
- Factory Method vs. Abstract Factory: An Abstract Factory is used to create a family of related products (Factory Method creates one product).
- Simple Factory returns instances of classes that have the same methods. They may be instances of different derived subclasses, or they may in fact be unrelated classes that just share the same interface. Either way, the methods in these class instances are the same and can be used interchangeably.
- Simple Factory یک الگوی طراحی واقعی نیست. اما به عنوان یک idiom برنامهنویسی بسیار رایج به کار گرفته میشود.
- وصل کردن کد به کلاسهای کانکرت، کد را شکننده و غیرقابل انعطاف میکند.
- جایگزینی اپراتور new با متدهای createConcrete
- میتوانیم از متد استاتیک در این الگو استفاده کنیم.
- استفاده از new باعث ایجاد نمونه از کلاسهای کانکرت میشود.
- استفاده از new یک نوع برنامهنویسی مرتبط با پیادهسازیست تا یک برنامهنویسی مرتبط به اینترفیس. (کد شکننده، خطا پذیر، غیر قابل انعطاف میشود)
- کلاسهای کانکرت معمولاً بیشتر از یک بار یک مکان نمونهبرداری (Instantiate) میشوند.
- بنابراین در صورتی که بخواهیم تغییر بدهیم باید تمامی نمونهبرداریها را در مکانهای مختلف را تغییر دهیم. که این کار طاقتفرسا، سخت و خطاپذیر است.
- Multiple Clinets neeeding same types of object
- Ensure consistent object initialization.
- Depenency
- Loose Couple
- Concrete classes (When you see
new
, thinkconcrete
) - Encapsulating object creation
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public class SimplePizzaFactory {
// میتوانیم این متود را استاتیک تعریف کنیم تا نیازی به ساخت شیء فکتوری نباشد و بتوانیم مستقیما از کلاس این متود را صدا بزنیم.
public Pizza createPizza(String type) {
Pizza pizza = null;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("pepperoni")) {
pizza = new PepperoniPizza();
} else if (type.equals("clam")) {
pizza = new ClamPizza();
} else if (type.equals("veggie")) {
pizza = new VeggiePizza();
}
return pizza;
}
}
- Simple Factory Pattern Side by Side with Abstract Pattern
- Simple Factory
- ص ۱۱۹ Head First Design Patterns
- The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate.
- Factory Method lets a class deffer instantiation to subclasses.
یک واسط برای تولید همهٔ خودرو طراحی میکنیم. (Car) که میتواند دارای توابع زیر باشد:
- نام خودرو
- تعداد سیلندرهای موتور
- ظرفیت (تعداد افراد)
واسط Car را برای ماشینهای مختلف پیادهسازی میکنیم.
- پیکان
- پراید
- سمند
واسط کارخانه makeCar()
هر کدام از کارخانهها باید واسط کارخانه را پیادهسازی کنند.
- PeycanFactory
- PrideFactory
- SamandFactory
Factory factory = new PeycanFactory()
Car car = factory.makeCar(مشخصات ماشین مثل رنگ و ...)
- کلاس SAXParserFactory
- http://javapapers.com/design-patterns/factory-method-pattern/
- http://stackoverflow.com/questions/9963090/factory-pattern-vs-factorymethod-pattern
- http://c2.com/cgi/wiki?FactoryMethodPattern
وقتی که ساخت یک شیئ زمانبر و هزینهبر باشد. بهتر است به جای این که برای تعداد زیادی از اشیاء تمام مراحل ساخت شیئ را طی کنیم، یک پروتوتایپ میسازیم سپس از روی آن نمونهبرداری میکنیم و طبق نیازهای خودمان، اشیاء جدید را اصلاح میکنیم. پروتوتایپ: نمونهٔ اولیه، اولین شیای که میسازیم و سپس تمامی اشیاء را از روی این شئ میسازیم.
مثال: ساختن انواع اقسام خانهها خیلی زمانبر است. همهٔ مراحل ساخت این خانهها هم یکسان است. در نتیجه به جای این که هر دفعه که مشتری خانهٔ خاصی (گلی، خشتی، سیمانی و ...) را طلب کرد. از یک نمونهٔ اولیه (پروتوتایپ) که قبلاً ساختهایم یکی فتوکپی میگیریم و سپس متناسب با نیاز مشتری آن را تغییر میدهیم و به مشتری تحویل میدهیم. اینطوری دیگر لازم نیست تمامی مراحل زمانبر ساخت خانه را از اول تکرار کنیم. (DRY)
DRY: Do Not Repeat Yourself
هدف: هر گاه بخواهیم مطمئن شویم که فقط یک نمونه از کلاس میتواند وجود داشته باشد، و دسترسی سراسری به آن داشته باشیم، از این الگو استفاده میکنیم.
- http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used
- http://www.yolinux.com/TUTORIALS/C++Singleton.html
- http://stackoverflow.com/questions/1008019/c-singleton-design-pattern
#الگوی طراحی Adapter هدف: این الگو، اجازه میدهد تا دو اینترفیس ناسازگار با یکدیگر کار کنند.
راههای پیادهسازی:
- چندوراثتی: کلاس Adapter، رو رابط Adaptee و Target را پیادهسازی میکند.
- ترکیب شی (Object Composition)؛ کلاس Adapter، رابط Target را پیادهسازی میکند و درخواستهای Target را برای Adaptee ترجمه میکند.
رابطیست (اینترفیس) که کلاینت از آن استفاده میکند.
شیئایست که با اشیاءای که با Target Interface مطابقت دارند، همکاری میکند.
یک رابط را به رابط دیگر (متناسب با درخواست کلاینت) تبدیل میکند. درخواست کلاینت را میگیرد، و آن را برای Adaptee Interface ترجمه میکند. این کلاس، رابط Target را پیادهسازی میکند
- java.io.InputStreamReader(InputStream)
- java.io.OutputStreamWriter(OutputStream)
- Publishers + Subscribers = Observer Pattern
- Subjects + Observers = Observer Pattern
- Loos coupling
- one-to-many relationship
- minimized interdependency
این الگو زمانی اعمال میشود که Subject-ها و Observer-ها Loose Couple باشند.
- Subject
- Observer
- ConcreteSubject
- ConcreteObserver
انعطافپذیری و تغییر رفتار نمونهها، در زمان اجرا.
##keywords
- wrapper
- aggregation relationship
- Open-Closed Principle (Classes should be open for extension, but closed for modification)
- Component تعریف اینترفیس و تعریف عملیات لازم.
- ConcreteComponent پیادهسازی اینترفیس و عملیات.
- Decorator این کلاس با کامپوننت، رابطهٔ اگریگیشن دارد و داخل خود، یک نمونه از کامپوننت را نگهداری میکند.
- ConcreteDecoratorA
فرض کنید که یک بستنی فروش سه نوع بستنی لیوانی، قیفی و چوبی دارد. این بستنی فروش هنگام فروش هر یک از این بستنیها طبق سلیقهٔ مشتری، بستنی را با عسل، کاکائو، شکلات، بادام و ... تزئین
میکند.
- http://javapapers.com/design-patterns/decorator-pattern/ یک مثال خوب و ساده با جاوا
- java.io.BufferedReader;
- java.io.FileReader;
- java.io.Reader;
MVC بیشتر یک معماری محسوب میشود تا یک الگوی طراحی
در الگوی طراحی استراتژی سعی میکنیم که رفتارهای غیرثابت و متفاوت (استراتژیهای متفاوت)
را از کلاس خارج کنیم و به طور مستقل آنها را کپسوله کنیم. در این صورت هر کلاس، هر کدام از الگوریتمهایی که نیاز داشته باشند را درون خود استفاده میکنند. همچنین این الگو اجازه میدهد تا هر یک از کلاسها هر وقت که بخواهند، استراتژی
خودشان را تغییر دهند.
- Behavioral Pattern
- Strategy at runtime (Change Behavior at Runtime)
- Composition (HAS-A is better than IS-A)
- Strategy lets the algorithm vary independently from clients that use it.
- Strategy at runtime (algorithms can be selected at runtime)
- انتخاب رفتار و
استراتژی
مناسب در runtime - رفتارها و
استراتژیهایی
که طول ساختار وراثتی کلاس تغییر میکند را مشخص کنید و آن رفتارها را از کلاس خارج کنید. و آنها را جداگانه کپسوله کنید. - Separating What changes from what stays the same.
- مزیت
استراتژی
این است که اگر بخواهیم در طول توسعهٔ نرمافزار رفتارها واستراتژیهای
جدیدی تعریف کنیم، نیازی به تغییر کلاسهای اصلی که از این رفتارهای استفاده میکنند نداریم.
- Strategy
- ConcreateStrategy
- Context
Context context = new Context(new ConcreateStrategy1());
context.AlgorithmInterface();
##مثال ۱
فرض کنید که کلاسی داریم به نام Car()
با متودی به نام run()
آنگاه میتوانیم آن را به صورت زیر پیاده کنیم:
Car car = new Car();
car.run();
حالا اگر بخواهیم هنگامی که ماشین روشن است، رفتار ماشین را تغییر دهیم چه کار کنیم؟ مثلاً بخواهیم در نرمافزار بازی دکمهٔ Boost
را شبیهسازی کنیم. چندین روش وجود دارد یکی این که از متغییرهای شرطی و ... استفاده کنیم راه دیگر استفاده از الگوی طراحی استراتژی
هست. مثلاً میتواین حین بازی موتور میاشین را عوض کنیم!! مثال:
Class Car()
{
this.motor = new Motor(this)
// passing "this" is important for the motor so it knows what it is running
method run()
{
this.motor.run()
}
method changeMotor(motor)
{
this.motor=motor
}
}
فرض کنید که یک کارخانهٔ تلفن گوشی همراه داریم. که انواع و اقسام گوشیها را تولید میکند. خب برای پیادهسازی کلاسهای این گوشیها چه کنیم؟
اولی: آیا میتوانیم تمامی رفتارهای مختلف و قابلیتهای گوشیهای مختلف رو در کلاس مادر تعریف کنیم؟
دومی: خیر، چون همهٔ گوشیها همهٔ قابلیتها را پیاده نمیکنند. بعضی از گوشیها دوربین دارند بعضی ندارند. بعضی رادیو دارند بعضی ندارند. بعضی قابلیت اتصال به کامپیوتر دارند و بعضی ندارند.
اولی: خب حالا چه کار کنیم؟
دومی: خب همهٔ قابلیتها را در کلاس مادر تعریف نمیکنیم. سعی میکنیم قابلیتها را در طول ساختار وراثت به سیستم اعمال کنیم.
اولی: اولاً این روش معقولانهای نیست چون برای اضافه کردن هر رفتار و قابلیت جدید باید کلاس و ساختار وراثت را دچار تغییر کنیم. دوم این که باعث ایجاد کدهای تکراری
میشود.
دومی: راهکار چیست؟
اولی: استفاده از الگوی استراتژی
یعنی رفتارهای متغیر را از رفتارهای ثابت جدا کنیم و رفتارهای متغیر را ساختار وراثتی کلاس خارج کنیم. و آنها را کپسوله کنیم.
- How does the Strategy Pattern work?
- ص ۳۴۹ کتاب Gang of for
- ص ۱۲ کتاب Head First Design Pattern