Skip to content
Milad Khajavi edited this page Mar 18, 2013 · 55 revisions

Design Principles

  1. Encapsulate what varies.

Object-modeling technique

دیاگرام‌های کتاب Gang of for بر مبنای OMT هست: Object-modeling technique OMT object diagram

#الگوی طراحی Builder

تعریف: الگوی طراحی Builder، روند ساخت یک شیء پیچیده را از نمایش آن جدا می‌کند به طوری که یک روند ساخت مشترک می‌تواند برای ساخت انوع نمایش‌ها به کار گرفته شود.

مثال: فرض کنید بخواهیم انواع و اقسام خانه‌ها را طراح کنیم. روند طراحی در تمامی خانه‌ها یکسان است. که به کلاس‌های زیر تقسیم می‌شود:

##Builder

  1. زیربنای آن را ایجاد می‌کنیم.
  2. ساختار و اسکلت آن را ایجاد می‌کنیم.
  3. سقف آن را می‌سازیم.
  4. فضای داخل خانه را طراحی می‌کنیم.

بنابراین برای طراحی همهٔ ساختمان‌ها یک رویهٔ یکسان داریم. بنابراین یک کلاس اینترفیس برای تمامی ساختمان‌ها با ۴ رویهٔ مذکور ایجاد می‌کنیم. که به آن Builder می‌گوییم.

در این مثال: HouseBuilder

ConcreateBuilder

حال به تعداد انواع خانه‌ها، اینترفیس Builder را پیاده‌سازی می‌کنم، در این مثال می‌توانیم خانهٔ خشتی، خانهٔ گلی، خانهٔ برفی، خانهٔ فلزی، خانهٔ فلزی، خانهٔ چوبی، خانهٔ سیمانی را بسازیم. به هر یک از این کلاس‌ها ConcreateBuilder می‌گوییم:

  1. KheshtiBuilder
  2. GeliBuilder
  3. BarfiBuilder
  4. FeleziBuiler

Director

پیمانکار ساختمان، ساختمان‌ها را از طریق اینترفیس House ایجاد می‌کند. (ورودی: یک نوع خانه از نوع HouseBuilder)

  1. ساخت زیربنا
  2. ساخت اسکلت و ساختار ساختمان
  3. ساخت سقف
  4. طراحی درون ساختمان

Product

محصول نهایی، حاصل ترکیب تمامی مراحل ساخت یک خانه است.

  1. خانهٔ گلی
  2. خانهٔ خشتی
  3. خانهٔ سیمانی و ...

Client

HouseBuilder builder = new KheshtiBuilder(); Director director = new Director(builder); director.construct();

بیشتر بخوانید:

  1. http://javapapers.com/design-patterns/builder-pattern/

الگوهای طراحی Factory

  1. Simple Factory (idiom)
  2. Factory Method Pattern
  3. Abstract Factory

نکات:

  1. Factories are used to encapsulate instantiation.
  2. Factory Method vs. Abstract Factory: An Abstract Factory is used to create a family of related products (Factory Method creates one product).

Simple Factory (Idiom)

  1. 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.
  2. Simple Factory یک الگوی طراحی واقعی نیست. اما به عنوان یک idiom برنامه‌نویسی بسیار رایج به کار گرفته می‌شود.
  3. وصل کردن کد به کلاس‌های کانکرت، کد را شکننده و غیرقابل انعطاف می‌کند.
  4. جایگزینی اپراتور new با متدهای createConcrete
  5. می‌توانیم از متد استاتیک در این الگو استفاده کنیم.
  6. استفاده از new باعث ایجاد نمونه از کلاس‌های کانکرت می‌شود.
  7. استفاده از new یک نوع برنامه‌نویسی مرتبط با پیاده‌سازی‌ست تا یک برنامه‌نویسی مرتبط به اینترفیس. (کد شکننده، خطا پذیر، غیر قابل انعطاف می‌شود)
  8. کلاس‌های کانکرت معمولاً بیشتر از یک بار یک مکان نمونه‌برداری (Instantiate) می‌شوند.
  9. بنابراین در صورتی که بخواهیم تغییر بدهیم باید تمامی نمونه‌برداری‌ها را در مکان‌های مختلف را تغییر دهیم. که این کار طاقت‌فرسا، سخت و خطاپذیر است.

چرا از Simple Factory استفاده می‌کنیم؟

  1. Multiple Clinets neeeding same types of object
  2. Ensure consistent object initialization.

SimpleFactory Simple Factory Simple Factory Diagram

Keywords:

  1. Depenency
  2. Loose Couple
  3. Concrete classes (When you see new, think concrete)
  4. 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;
	}
}

pizza Simple Factory

اطلاعات بیشتر

  1. Simple Factory Pattern Side by Side with Abstract Pattern
  2. Simple Factory
  3. ص ۱۱۹ Head First Design Patterns

الگوی طراحی Factory Method (Virtual Constructor)

  1. The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate.
  2. Factory Method lets a class deffer instantiation to subclasses.

مثال: ساخت خودروهای متنوع

Product

یک واسط برای تولید همهٔ خودرو طراحی می‌کنیم. (Car) که می‌تواند دارای توابع زیر باشد:

  1. نام خودرو
  2. تعداد سیلندرهای موتور
  3. ظرفیت (تعداد افراد)

ConcreateProduct

واسط Car را برای ماشین‌های مختلف پیاده‌سازی می‌کنیم.

  1. پیکان
  2. پراید
  3. سمند

Creator/Factory

واسط کارخانه makeCar()

ConcreteCreator/ConcreteFactry

هر کدام از کارخانه‌ها باید واسط کارخانه را پیاده‌سازی کنند.

  1. PeycanFactory
  2. PrideFactory
  3. SamandFactory

Client

Factory  factory =  new PeycanFactory()
Car car = factory.makeCar(مشخصات ماشین مثل رنگ و ...)

Mobile Factory

بیشتر بخوانید

  1. کلاس SAXParserFactory
  2. http://javapapers.com/design-patterns/factory-method-pattern/
  3. http://stackoverflow.com/questions/9963090/factory-pattern-vs-factorymethod-pattern
  4. http://c2.com/cgi/wiki?FactoryMethodPattern

الگوی طراحی Factory

بیشتر بخوانید

  1. Simple Factory vs. Factory Method vs. Abstract Factory

الگوی طراحی Prototype

وقتی که ساخت یک شیئ زمان‌بر و هزینه‌بر باشد. بهتر است به جای این که برای تعداد زیادی از اشیاء تمام مراحل ساخت شیئ را طی کنیم، یک پروتوتایپ می‌سازیم سپس از روی آن نمونه‌برداری می‌کنیم و طبق نیازهای خودمان، اشیاء جدید را اصلاح می‌کنیم. پروتوتایپ: نمونهٔ اولیه، اولین شی‌ای که می‌سازیم و سپس تمامی اشیاء را از روی این شئ می‌سازیم.

مثال: ساختن انواع اقسام خانه‌ها خیلی زمان‌بر است. همهٔ مراحل ساخت این خانه‌ها هم یکسان است. در نتیجه به جای این که هر دفعه که مشتری خانهٔ خاصی (گلی، خشتی، سیمانی و ...) را طلب کرد. از یک نمونهٔ اولیه (پروتوتایپ) که قبلاً ساخته‌ایم یکی فتوکپی می‌گیریم و سپس متناسب با نیاز مشتری آن را تغییر می‌دهیم و به مشتری تحویل می‌دهیم. اینطوری دیگر لازم نیست تمامی مراحل زمان‌بر ساخت خانه را از اول تکرار کنیم. (DRY)

بیشتر بخوانید

  1. http://www.codeproject.com/Articles/42582/Prototype-Design-Pattern

DRY: Do Not Repeat Yourself

الگوی طراحی Singleton

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

بیشتر بخوانید

  1. http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used
  2. http://www.yolinux.com/TUTORIALS/C++Singleton.html
  3. http://stackoverflow.com/questions/1008019/c-singleton-design-pattern

#الگوی طراحی Adapter هدف: این الگو، اجازه می‌دهد تا دو اینترفیس ناسازگار با یکدیگر کار کنند.

راه‌های پیاده‌سازی:

  1. چندوراثتی: کلاس Adapter، رو رابط Adaptee و Target را پیاده‌سازی می‌کند.
  2. ترکیب شی (Object Composition)؛ کلاس Adapter، رابط Target را پیاده‌سازی می‌کند و درخواست‌های Target را برای Adaptee ترجمه می‌کند.

Target

رابطی‌ست (اینترفیس) که کلاینت از آن استفاده می‌کند.

Client

شیئ‌ای‌ست که با اشیاء‌ای که با Target Interface مطابقت دارند، همکاری می‌کند.

Adaptee

Adapter

یک رابط را به رابط دیگر (متناسب با درخواست کلاینت) تبدیل می‌کند. درخواست کلاینت را می‌گیرد، و آن را برای Adaptee Interface ترجمه می‌کند. این کلاس، رابط Target را پیاده‌سازی می‌کند

بیشتر بخوانید

  1. java.io.InputStreamReader(InputStream)
  2. java.io.OutputStreamWriter(OutputStream)

الگوی طراحی Observer

  1. Publishers + Subscribers = Observer Pattern
  2. Subjects + Observers = Observer Pattern

Keywords:

  1. Loos coupling
  2. one-to-many relationship
  3. minimized interdependency

این الگو زمانی اعمال می‌شود که Subject-ها و Observer-ها Loose Couple باشند.

Components

  1. Subject
  2. Observer
  3. ConcreteSubject
  4. ConcreteObserver

الگوی طراحی Decorator

انعطاف‌پذیری و تغییر رفتار نمونه‌ها، در زمان اجرا.

##keywords

  1. wrapper
  2. aggregation relationship
  3. Open-Closed Principle (Classes should be open for extension, but closed for modification)

Components

  1. Component تعریف اینترفیس و تعریف عملیات لازم.
  2. ConcreteComponent پیاده‌سازی اینترفیس و عملیات.
  3. Decorator این کلاس با کامپوننت، رابطهٔ اگریگیشن دارد و داخل خود، یک نمونه از کامپوننت را نگهداری می‌کند.
  4. ConcreteDecoratorA

مثال ۱

فرض کنید که یک بستنی فروش سه نوع بستنی لیوانی، قیفی و چوبی دارد. این بستنی فروش هنگام فروش هر یک از این بستنی‌ها طبق سلیقهٔ مشتری، بستنی را با عسل، کاکائو، شکلات، بادام و ... تزئین می‌کند.

بیشتر بخوانید

  1. http://javapapers.com/design-patterns/decorator-pattern/ یک مثال خوب و ساده با جاوا
  2. java.io.BufferedReader;
  3. java.io.FileReader;
  4. java.io.Reader;

MVC

MVC بیشتر یک معماری محسوب می‌شود تا یک الگوی طراحی

  1. http://leepoint.net/notes-java/GUI/structure/40mvc.html

Strategy pattern (policy pattern)

در الگوی طراحی استراتژی سعی می‌کنیم که رفتارهای غیرثابت و متفاوت (استراتژی‌های متفاوت) را از کلاس خارج کنیم و به طور مستقل آن‌ها را کپسوله کنیم. در این صورت هر کلاس، هر کدام از الگوریتم‌هایی که نیاز داشته باشند را درون خود استفاده می‌کنند. همچنین این الگو اجازه می‌دهد تا هر یک از کلاس‌ها هر وقت که بخواهند، استراتژی خودشان را تغییر دهند.

Keywords

  1. Behavioral Pattern
  2. Strategy at runtime (Change Behavior at Runtime)
  3. Composition (HAS-A is better than IS-A)

نکات

  1. Strategy lets the algorithm vary independently from clients that use it.
  2. Strategy at runtime (algorithms can be selected at runtime)
  3. انتخاب رفتار و استراتژی مناسب در runtime
  4. رفتارها و استراتژی‌هایی که طول ساختار وراثتی کلاس تغییر می‌کند را مشخص کنید و آن رفتارها را از کلاس خارج کنید. و آن‌ها را جداگانه کپسوله کنید.
  5. Separating What changes from what stays the same.
  6. مزیت استراتژی این است که اگر بخواهیم در طول توسعهٔ نرم‌افزار رفتارها و استراتژی‌های جدیدی تعریف کنیم، نیازی به تغییر کلاس‌های اصلی که از این رفتارهای استفاده می‌کنند نداریم.

Participants

  1. Strategy
  2. ConcreateStrategy
  3. Context

Diagram

StrategyPattern

Client Code

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 
    }

}

مثال ۲

فرض کنید که یک کارخانهٔ تلفن گوشی همراه داریم. که انواع و اقسام گوشی‌ها را تولید می‌کند. خب برای پیاده‌سازی کلاس‌های این گوشی‌ها چه کنیم؟

اولی: آیا می‌توانیم تمامی رفتارهای مختلف و قابلیت‌های گوشی‌های مختلف رو در کلاس مادر تعریف کنیم؟

دومی: خیر، چون همهٔ‌ گوشی‌ها همهٔ قابلیت‌ها را پیاده نمی‌کنند. بعضی از گوشی‌ها دوربین دارند بعضی ندارند. بعضی رادیو دارند بعضی ندارند. بعضی قابلیت اتصال به کامپیوتر دارند و بعضی ندارند.

اولی: خب حالا چه کار کنیم؟

دومی: خب همهٔ قابلیت‌ها را در کلاس مادر تعریف نمی‌کنیم. سعی می‌کنیم قابلیت‌ها را در طول ساختار وراثت به سیستم اعمال کنیم.

اولی: اولاً‌ این روش معقولانه‌ای نیست چون برای اضافه کردن هر رفتار و قابلیت جدید باید کلاس و ساختار وراثت را دچار تغییر کنیم. دوم این که باعث ایجاد کدهای تکراری می‌شود.

دومی: راهکار چیست؟

اولی: استفاده از الگوی استراتژی یعنی رفتارهای متغیر را از رفتارهای ثابت جدا کنیم و رفتارهای متغیر را ساختار وراثتی کلاس خارج کنیم. و آن‌ها را کپسوله کنیم.

اطلاعات بیشتر

  1. How does the Strategy Pattern work?
  2. ص ۳۴۹ کتاب Gang of for
  3. ص ۱۲ کتاب Head First Design Pattern
Clone this wiki locally