├── .gitignore ├── .gitmodules ├── Behavioural ├── Strategy │ ├── img │ │ └── StrategyStructure.gif │ ├── Classic │ │ └── C++ │ │ │ └── main.cpp │ └── Readme.md ├── Mediator │ ├── Chatroom │ │ └── C++ │ │ │ └── Main.cpp │ ├── README.md │ └── Classic │ │ └── C++ │ │ └── Main.cpp ├── Interpreter │ ├── README.md │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ └── RomanNumeralInterpreter │ │ └── C++ │ │ └── Main.cpp ├── Memento │ ├── README.md │ └── Classic │ │ └── C++ │ │ └── Main.cpp ├── Command │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── StockAgent │ │ └── C++ │ │ │ └── Main.cpp │ ├── DeviceController │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── Observer │ ├── README.md │ └── Classic │ │ └── C++ │ │ └── Main.cpp ├── Visitor │ ├── AnimalVisitor │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── TemplateMethod │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── DocumentGenerator │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── State │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── README.md │ └── SunState │ │ └── Main.cpp ├── ChainOfResponsibility │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── Iterator │ ├── README.md │ ├── Classic │ │ └── C++ │ │ │ ├── 1 │ │ │ └── Main.cpp │ │ │ └── 2 │ │ │ └── Main.cpp │ └── AnimalIterator │ │ └── Main.cpp └── README.md ├── Creational ├── FactoryMethod │ ├── img │ │ └── FactoryMethod.jpg │ ├── FactoryMehtod │ │ └── C++ │ │ │ ├── Main.cpp │ │ │ ├── Factory.cpp │ │ │ └── Factory.h │ ├── MobileFactoryMethod │ │ └── C++ │ │ │ └── main.cpp │ └── Readme.md ├── SimpleFactory │ ├── img │ │ ├── SimpleFactory.jpg │ │ ├── SimpleFactory.png │ │ └── simplefactorystructure.gif │ ├── SimplePizzaFactory │ │ └── C++ │ │ │ └── main.cpp │ └── Readme.md ├── AbstractFactory │ ├── img │ │ └── AbstractFactory.jpg │ ├── AbstractFactory │ │ ├── C++ │ │ │ ├── Makefile │ │ │ ├── client.hpp │ │ │ ├── main.cpp │ │ │ ├── AbstractFactory.hpp │ │ │ └── AbstractFactory.cpp │ │ └── C++-example2 │ │ │ └── main.cpp │ ├── AbstractMobileFactory │ │ ├── README │ │ └── main.cpp │ └── README.md ├── Singleton │ ├── Classic │ │ └── C++ │ │ │ └── main.cpp │ └── README.md ├── Prototype │ ├── C++ │ │ └── Prototype.cpp │ └── README.md ├── README.md └── Builder │ ├── Classic │ └── C++ │ │ └── Main.cpp │ └── README.md ├── Structural ├── Adapter │ ├── Adapter │ │ └── C++ │ │ │ ├── main.cpp │ │ │ ├── Adapter.cpp │ │ │ └── Adapter.hpp │ ├── DuckAdapter │ │ └── C++ │ │ │ ├── Makefile │ │ │ ├── Duck.hpp │ │ │ ├── Turkey.hpp │ │ │ ├── WildTurkey.hpp │ │ │ ├── MallardDuck.hpp │ │ │ ├── MallardDuck.cpp │ │ │ ├── WildTurkey.cpp │ │ │ ├── TurkeyAdapter.hpp │ │ │ ├── TurkeyAdapter.cpp │ │ │ └── main.cpp │ └── README.md ├── Flyweight │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── README.md │ └── Characters │ │ └── C++ │ │ └── Main.cpp ├── Proxy │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── ImageProxy │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── Composite │ ├── README.md │ └── Classic │ │ └── Main.cpp ├── README.md ├── Bridge │ ├── TvBridge │ │ └── C++ │ │ │ └── Main.cpp │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── VehicleWorkshopBridge │ │ └── C++ │ │ │ └── Main.cpp │ └── README.md ├── Decorator │ ├── Classic │ │ └── C++ │ │ │ └── Main.cpp │ ├── Java │ │ └── TestDecorator.java │ └── README.md └── Facade │ ├── Classic │ └── C++ │ │ └── Main.cpp │ └── README.md ├── Architecture └── MVC │ ├── Javascript │ └── HelloWorld │ │ └── index.html │ └── README.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | #*# 3 | *# 4 | #* 5 | *.o 6 | *.bin 7 | *.dot 8 | .#* 9 | *.swp 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Design-Patterns.wiki"] 2 | path = Design-Patterns.wiki 3 | url = git@github.com:khajavi/Design-Patterns.wiki.git 4 | -------------------------------------------------------------------------------- /Behavioural/Strategy/img/StrategyStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Behavioural/Strategy/img/StrategyStructure.gif -------------------------------------------------------------------------------- /Creational/FactoryMethod/img/FactoryMethod.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Creational/FactoryMethod/img/FactoryMethod.jpg -------------------------------------------------------------------------------- /Creational/SimpleFactory/img/SimpleFactory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Creational/SimpleFactory/img/SimpleFactory.jpg -------------------------------------------------------------------------------- /Creational/SimpleFactory/img/SimpleFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Creational/SimpleFactory/img/SimpleFactory.png -------------------------------------------------------------------------------- /Creational/AbstractFactory/img/AbstractFactory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Creational/AbstractFactory/img/AbstractFactory.jpg -------------------------------------------------------------------------------- /Creational/SimpleFactory/img/simplefactorystructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khajavi/Practical-Design-Patterns/HEAD/Creational/SimpleFactory/img/simplefactorystructure.gif -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++/Makefile: -------------------------------------------------------------------------------- 1 | main: 2 | g++ -c AbstractFactory.cpp -o AbstractFactory.o 3 | g++ -c main.cpp -o main.o 4 | g++ -o AbstractFactory.bin AbstractFactory.o main.o 5 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++/client.hpp: -------------------------------------------------------------------------------- 1 | 2 | class Client { 3 | public: 4 | Client(AbstractFactory*); 5 | private: 6 | AbstractProductA* a; 7 | AbstractProductB* b; 8 | }; 9 | -------------------------------------------------------------------------------- /Creational/FactoryMethod/FactoryMehtod/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "Factory.h" 2 | #include 3 | 4 | int main (int argc, char const* argv[]) { 5 | Factory* factory = new ConcreteFactory(); 6 | factory->AnOperation(); 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Structural/Adapter/Adapter/C++/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Adapter.hpp" 2 | #include 3 | 4 | int main() { 5 | Adaptee* pAdaptee = new Adaptee(); 6 | Target* pTarget = new Adapter(pAdaptee); 7 | pTarget->Request(); 8 | 9 | delete pTarget; 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/Makefile: -------------------------------------------------------------------------------- 1 | all: main.o MallardDuck.o WildTurkey.o TurkeyAdapter.o Duck.o 2 | g++ main.o MallardDuck.o WildTurkey.o TurkeyAdapter.o Duck.o -o main.bin 3 | 4 | main.o: main.cpp 5 | g++ -c main.cpp -o main.o 6 | 7 | MallardDuck.o: MallardDuck.h Duck.h 8 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/Duck.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #ifndef DUCK_HPP 6 | #define DUCK_HPP 7 | 8 | class Duck { 9 | public: 10 | virtual void quack() = 0; 11 | virtual void fly() = 0; 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/Turkey.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #ifndef TURKEY_H 6 | #define TURKEY_H 7 | 8 | class Turkey { 9 | public: 10 | virtual void gobble() = 0; 11 | virtual void fly() = 0; 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/WildTurkey.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #ifndef WILD_TURKEY_HPP 6 | #define WILD_TURKEY_HPP 7 | #include "Turkey.hpp" 8 | 9 | class WildTurkey : public Turkey { 10 | void gobble(); 11 | void fly(); 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/MallardDuck.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #ifndef MALLARD_DUCK_HPP 6 | #define MALLARD_DUCK_HPP 7 | 8 | #include "Duck.hpp" 9 | 10 | class MallardDuck : public Duck { 11 | void quack(); 12 | void fly(); 13 | }; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Behavioural/Mediator/Chatroom/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class AbstractChatroom { 5 | 6 | }; 7 | 8 | 9 | class Chatroom : public AbstractChatroom { 10 | 11 | }; 12 | 13 | 14 | class AbstactColleague { 15 | 16 | }; 17 | 18 | 19 | 20 | 21 | int main() { 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Creational/FactoryMethod/FactoryMehtod/C++/Factory.cpp: -------------------------------------------------------------------------------- 1 | #include "Factory.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | void Factory::AnOperation() { 7 | Product* p = FactoryMethod(); 8 | std::cout << "An operation of product\n"; 9 | } 10 | 11 | Product* ConcreteFactory::FactoryMethod() { 12 | return new ConcreteProduct(); 13 | } 14 | -------------------------------------------------------------------------------- /Structural/Flyweight/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Flyweight { 6 | public: 7 | char* getIntrinsicState() { 8 | 9 | } 10 | 11 | virtual void operation( char*& ExtrinsicState ) = 0; 12 | 13 | protected: 14 | Flyweight( const char* 15 | }; 16 | 17 | int main() { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/MallardDuck.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #include "MallardDuck.hpp" 6 | #include 7 | 8 | using namespace std; 9 | 10 | void MallardDuck::quack() { 11 | cout << "Quack quack" << endl; 12 | } 13 | 14 | void MallardDuck::fly() { 15 | cout << "I'm flying" << endl; 16 | } 17 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++/main.cpp: -------------------------------------------------------------------------------- 1 | //source: https://github.com/wxjeacen/DesignPattern.git 2 | 3 | #include "AbstractFactory.hpp" 4 | #include 5 | 6 | int main(int argc, char* argv[]) { 7 | 8 | ConcreateFactory1 *pFactory1 = new ConcreateFactory1(); 9 | AbstractProductA *pProductA = pFactory1->CreateProductA(); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/WildTurkey.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #include "WildTurkey.hpp" 6 | #include 7 | using namespace std; 8 | 9 | void WildTurkey::gobble() { 10 | cout << "Gobble gobble" << endl; 11 | } 12 | 13 | void WildTurkey::fly() { 14 | cout << "I'm flying a short distance" << endl; 15 | } 16 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/TurkeyAdapter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #ifndef TURKEY_ADAPTER_HPP 6 | #define TURKEY_ADAPTER_HPP 7 | #include "Turkey.hpp" 8 | #include "Duck.hpp" 9 | 10 | class TurkeyAdapter : public Duck { 11 | public: 12 | TurkeyAdapter(Turkey*); 13 | void quack(); 14 | void fly(); 15 | private: 16 | Turkey* m_turkey; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/TurkeyAdapter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #include "TurkeyAdapter.hpp" 6 | 7 | TurkeyAdapter::TurkeyAdapter(Turkey* turkey) { 8 | m_turkey = turkey; 9 | } 10 | 11 | void TurkeyAdapter::quack() { 12 | m_turkey->gobble(); 13 | } 14 | 15 | void TurkeyAdapter::fly() { 16 | for(int i = 0; i < 5; i++) { 17 | m_turkey->fly(); 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Creational/FactoryMethod/FactoryMehtod/C++/Factory.h: -------------------------------------------------------------------------------- 1 | #ifndef FACTORY_H 2 | #define FACTORY_H 3 | 4 | class Product { 5 | 6 | }; 7 | 8 | class ConcreteProduct : public Product { 9 | 10 | }; 11 | 12 | class Factory { 13 | public: 14 | void AnOperation(); 15 | protected: 16 | virtual Product* FactoryMethod() = 0; 17 | }; 18 | 19 | class ConcreteFactory : public Factory { 20 | protected: 21 | virtual Product* FactoryMethod(); 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Structural/Adapter/DuckAdapter/C++/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from Head first Design book, page 238-240 3 | */ 4 | 5 | #include "MallardDuck.hpp" 6 | #include "WildTurkey.hpp" 7 | #include "TurkeyAdapter.hpp" 8 | #include "Duck.hpp" 9 | 10 | 11 | int main() { 12 | MallardDuck* duck = new MallardDuck(); 13 | 14 | WildTurkey* turkey = new WildTurkey(); 15 | Duck* turkeyAdapter = new TurkeyAdapter(turkey); 16 | 17 | turkeyAdapter->quack(); 18 | turkeyAdapter->fly(); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Structural/Adapter/Adapter/C++/Adapter.cpp: -------------------------------------------------------------------------------- 1 | #include "Adapter.hpp" 2 | #include 3 | using namespace std; 4 | 5 | void Adaptee::SpecialRequest() { 6 | cout << "Special Request of Adaptee\n" << endl; 7 | } 8 | 9 | Adapter::Adapter(Adaptee* pAdaptee) 10 | :m_pAdaptee(pAdaptee) 11 | { 12 | } 13 | 14 | Adapter::~Adapter() { 15 | delete m_pAdaptee; 16 | m_pAdaptee = NULL; 17 | } 18 | 19 | void Adapter::Request() { 20 | cout << "Request of Adapter\n" << endl; 21 | m_pAdaptee->SpecialRequest(); 22 | } 23 | -------------------------------------------------------------------------------- /Structural/Adapter/Adapter/C++/Adapter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ADAPTER_H 2 | #define ADAPTER_H 3 | 4 | class Target { 5 | public: 6 | Target() {} 7 | virtual ~Target() {} 8 | virtual void Request() = 0; 9 | }; 10 | 11 | class Adaptee { 12 | public: 13 | Adaptee() {} 14 | ~Adaptee() {} 15 | void SpecialRequest(); 16 | }; 17 | 18 | class Adapter 19 | :public Target { 20 | public: 21 | Adapter(Adaptee* pAdaptee); 22 | virtual ~Adapter(); 23 | virtual void Request(); 24 | 25 | private: 26 | Adaptee* m_pAdaptee; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Creational/Singleton/Classic/C++/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Singleton { 6 | private: 7 | Singleton() { 8 | cout << "new Singleton is called" << endl; 9 | } 10 | static Singleton* uniqueInstance; 11 | public: 12 | static Singleton* getInstance() { 13 | if (!uniqueInstance) { 14 | uniqueInstance = new Singleton(); 15 | } 16 | return uniqueInstance; 17 | } 18 | }; 19 | 20 | Singleton* Singleton::uniqueInstance = NULL; 21 | 22 | 23 | int main (int argc, char const* argv[]) { 24 | 25 | Singleton::getInstance(); 26 | Singleton::getInstance(); 27 | Singleton::getInstance(); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Structural/Proxy/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Subject { 5 | public: 6 | virtual void request() = 0; 7 | }; 8 | 9 | class RealSubject : public Subject { 10 | public: 11 | virtual void request() { 12 | cout << "Request by RealSubject" << endl; 13 | } 14 | }; 15 | 16 | class Proxy : public Subject { 17 | public: 18 | virtual void request() { 19 | cout << "Request by Proxy" << endl; 20 | if ( _realSubject == NULL ) { 21 | _realSubject = new RealSubject(); 22 | } 23 | _realSubject->request(); 24 | } 25 | private: 26 | RealSubject* _realSubject; 27 | }; 28 | 29 | int main() { 30 | 31 | Subject* proxy = new Proxy(); 32 | proxy->request(); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Behavioural/Interpreter/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | یک بازنمایی برای گرامر زبان داده شده تعریف می‌کند و مفسر توسط این باز نمایی، جملات زبان را تفسیر می کند. 4 | 5 | # ساختار 6 | ![Interpreter UML](http://javaobsession.files.wordpress.com/2010/07/interpreter-pattern.png) 7 | 8 | # نکات طراحی 9 | وقتی از این الگو استفاده کنید که 10 | - گرامر ساده‌ای وجود دارد که می‌تواند توسط درخت گرامر (Syntax tree) بازنمایی شود. 11 | - کارایی زیاد مهم نیست. 12 | 13 | # مثال 14 | - تبدیل عددنویسی رومی به عددنویسی دهدهی 15 | - ماشین حسابی که بتواند عبارات ریاضی پی‌درپی را محاسبه کند. 16 | 17 | 18 | # مثال‌های واقعی 19 |
20 | - java.util.Pattern 21 | - java.text.Normalizer 22 | - All subclasses of java.text.Format 23 | - All subclasses of javax.el.ELResolver 24 | -------------------------------------------------------------------------------- /Structural/Proxy/ImageProxy/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Graphic { 5 | public: 6 | virtual void draw() = 0; 7 | }; 8 | 9 | class Image : public Graphic { 10 | public: 11 | Image() { 12 | // load image frome disk. 13 | } 14 | virtual void draw() { 15 | cout << "Draw real image." << endl; 16 | } 17 | }; 18 | 19 | class ProxyImage : public Graphic { 20 | public: 21 | virtual void draw() { 22 | if(_image == NULL) { 23 | _image = new Image(); 24 | cout << "Real image is assigned." << endl; 25 | } 26 | _image->draw(); 27 | } 28 | private: 29 | Image* _image; 30 | }; 31 | 32 | int main() { 33 | 34 | Graphic* proxyImage = new ProxyImage(); 35 | proxyImage->draw(); 36 | proxyImage->draw(); 37 | proxyImage->draw(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractMobileFactory/README: -------------------------------------------------------------------------------- 1 | در این مثال: 2 | کارخانه‌ها به سه دسته تقسیم می‌شوند (نوکیا/سامسونگ/اچ‌تی‌سی) و محصولات به دو دستهٔ (گوشی‌های هوشمند/گوشی‌های غیرهوشمند) 3 | در این مثال ابتدا یک کلاس انتزاعی از کارخانه‌ها می‌سازیم که این کلاس دو متد دارد، یکی ساخت گوشی هوشمند آن کارخانه و دیگری ساخت گوشی غیرهوشمند آن کارخانه. 4 | سپس از کلاس انتزاعی کارخانه، سه کلاس نوکیا و سامسونگ و اچ‌تی‌سی می‌سازیم که هر کدام از این کارخانه‌ها دو نوع گوشی هوشمند و غیر هوشمند خود را می‌سازند. 5 | در این مثال، کلاینت ما از نام گوشی‌ها با خبر نیست. مثلاً نمی‌داند که گوشی هوشمند سامسونگ چیست. کلاینت درخواستش را اعلام می‌کند. مثلاً می‌گوید گوشی هوشمند سامسونگ را می‌خواهم. کلاس کانکرت کارخانهٔ سامسونگ درون کلاس ساخت گوشی هوشمند خود، گالاکسی‌اس۲ را می‌سازد. 6 | متن کامل مثال: http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa 7 | -------------------------------------------------------------------------------- /Behavioural/Mediator/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | شیء‌ای را تعریف می‌کند که نحوهٔ ارتباط بین مجوعه‌ای از اشیاء را کپسوله می‌کند. این الگو با جلوگیری ارتباط صریح بین اشیاء از جفتگری ضعیف (loose coupling) پشتیبانی می‌کند. 4 | 5 | # ساختار 6 | ![UML](http://i.imgur.com/0wPMI3h.png) 7 | 8 | # نکات طراحی 9 | - مانند hub عمل می‌کند. 10 | 11 | # اجزاء طراحی 12 | - Mediator 13 | - ConcreteMediator 14 | - Colleague 15 | - ConcreteColleague 16 | 17 | # مثال 18 | - اتاق چت 19 | - برج مراقبت هواپیماها 20 | - روترها 21 | 22 | # مثال‌های واقعی 23 |
24 | - java.util.Timer (all scheduleXXX() methods) 25 | - java.util.concurrent.Executor#execute() 26 | - java.util.concurrent.ExecutorService (the invokeXXX() and submit() methods) 27 | - java.util.concurrent.ScheduledExecutorService (all scheduleXXX() methods) 28 | - java.lang.reflect.Method#invoke() 29 | -------------------------------------------------------------------------------- /Structural/Composite/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | اشیاء را درون ساختار درختی ترکیب می‌کند تا سسله-مراتب جز-کل را ارائه کند. الگوی کامپوزت به کارخواه‌ها اجازه می‌دهد تا با اشیاء تکی و با اشیائی که ترکیبی از اشیاء هستند، به یک صورت رفتار کند. 4 | 5 | # ساختار 6 | ![Composite UML](http://javaobsession.files.wordpress.com/2010/07/composite-pattern1.png) 7 | 8 | # نکات طراحی 9 | زمانی از این الگو استفاده کنید که 10 | - نیاز به ساختار سسله‌مراتبی شاخه-برگ، جزء-کل، محتوی-محصور داشته باشید. 11 | - نیاز دارید که با اشیاء و ترکیبی از اشیاء به طور یکسان رفتار کنید. 12 | 13 | برای اینکه کامپوزیت بتواند با تمامی اشیاء درخت به صورت یکسان رفتار کند، یک واسط به نام Component ایجاد کرده است تا هر دو نوع برگ‌ها و اشیاء کامپوزیت آن را پیاده‌سازی می‌کنند. 14 | 15 | # مثال‌های واقعی 16 |
17 | - java.awt.Container#add(Component) (practically all over Swing thus) 18 | - javax.faces.component.UIComponent#getChildren() (practically all over JSF UI thus) 19 | -------------------------------------------------------------------------------- /Creational/Prototype/C++/Prototype.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Prototype { 4 | public: 5 | virtual ~Prototype() { } 6 | virtual Prototype* clone() const = 0; 7 | }; 8 | 9 | class ConcreatePrototype: public Prototype { 10 | public: 11 | ConcreatePrototype(int x) 12 | :x_(x) { 13 | } 14 | ConcreatePrototype(const ConcreatePrototype& p) 15 | :x_(p.x_) { 16 | } 17 | virtual Prototype* clone() const { 18 | return new ConcreatePrototype(*this); 19 | } 20 | 21 | void setX(int x) { 22 | x_ = x; 23 | } 24 | 25 | int getX() const { 26 | return x_; 27 | } 28 | 29 | void printX() const { 30 | std::cout << "Value :" << x_ << std::endl; 31 | } 32 | private: 33 | int x_; 34 | }; 35 | 36 | 37 | int main() { 38 | 39 | Prototype* prototype = new ConcreatePrototype(1000); 40 | for (int i = 1; i < 100; i++) { 41 | ConcreatePrototype* tempotype = 42 | dynamic_cast(prototype->clone()); 43 | tempotype->setX(tempotype->getX() * i); 44 | tempotype->printX(); 45 | } 46 | 47 | return 0; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Behavioural/Memento/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | بدون تخلف از کپسوله‌سازی، وضعیت داخلی شیء ضبط و استخراج می‌کند از این رو شیء بعداً می‌تواند به این حالت برگردد. 4 | 5 | # ساختار 6 | ![Memento UML](http://i.imgur.com/xWJbL62.png) 7 | 8 | # نکات طراحی 9 | - در سی‌پلاس‌پلاس می‌توانیم برای طراحی Memento از friend استفاده کنیم و متدهای getState و setState را private کنیم. 10 | 11 | # اجزاء الگو 12 | - Memento 13 | - Orginator 14 | - Caretaker 15 | 16 | # مثال‌های واقعی 17 |
18 | - java.util.Date (the setter methods do that, Date is internally represented by a long value) 19 | - All implementations of java.io.Serializable 20 | - All implementations of javax.faces.component.StateHolder 21 | 22 |
23 | # اطلاعات بیشتر 24 | 25 | 1. [یک پیاده‌سازی خیلی خوب از Memento در جاوا](http://sourcemaking.com/design_patterns/memento/java/1) 26 | 2. [常见设计模式的解析和实现(C++)之十九-Memento模式](http://www.cppblog.com/converse/archive/2006/08/09/11063.html) 27 | 2. [پیاده‌سازی Memento در C++ به همراه کلاس Caretaker](http://d.hatena.ne.jp/teramonagi/20110427/1303905634) 28 | -------------------------------------------------------------------------------- /Behavioural/Command/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Command { 5 | public: 6 | virtual void execute() = 0; 7 | }; 8 | 9 | class Receiver { 10 | public: 11 | void action() { 12 | cout << "Receiver Action" << endl; 13 | } 14 | }; 15 | 16 | class Invoker { 17 | public: 18 | Invoker(Command* command) 19 | :_command(command) { 20 | } 21 | void invoke() { 22 | _command->execute(); 23 | } 24 | private: 25 | Command* _command; 26 | }; 27 | 28 | class ConcreteCommand : public Command { 29 | public: 30 | ConcreteCommand(Receiver* receiver) 31 | :_receiver(receiver) { 32 | 33 | } 34 | 35 | virtual void execute() { 36 | _receiver->action(); 37 | 38 | cout << "Execute by ConcreteCommand" << endl; 39 | } 40 | private: 41 | Receiver* _receiver; 42 | }; 43 | 44 | 45 | int main (int argc, char const* argv[]) { 46 | 47 | Receiver* receiver = new Receiver(); 48 | Command* command = new ConcreteCommand( receiver ); 49 | Invoker* invoker = new Invoker( command ); 50 | 51 | invoker->invoke(); 52 | 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Behavioural/Observer/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | وابستگی یک-به-چند بین اشیاء تعریف می‌کند بنابراین وقتی یک شیء وضعیت‌اش را تغییر می‌دهد، تمامی اشیاء وابسته به آن از آن تغییر مطلع شده و به صورت خودکار به روز می‌شوند. 4 | 5 | # ساختار 6 | ![Observer UML](http://www.dofactory.com/Patterns/Diagrams/observer.gif) 7 | 8 | 9 | # اجزاء الگو 10 | - Subject 11 | - Observer 12 | - ConcreteSubject 13 | - ConcreteObserver 14 | 15 | 16 | # نکات طراحی 17 | - Publishers + Subscribers = Observer Pattern 18 | - Subjects + Observers = Observer Pattern 19 | مفاهیم مرتبط 20 | - Loos coupling 21 | - one-to-many relationship 22 | - minimized interdependency 23 | 24 | این الگو زمانی اعمال می‌شود که Subject-ها و Observer-ها Loose Couple باشند. 25 | 26 | # مثال‌های واقعی 27 |
28 | - java.util.Observer/java.util.Observable (rarely used in real world though) 29 | - All implementations of java.util.EventListener (practically all over Swing thus) 30 | - javax.servlet.http.HttpSessionBindingListener 31 | - javax.servlet.http.HttpSessionAttributeListener 32 | - javax.faces.event.PhaseListener 33 | 34 | -------------------------------------------------------------------------------- /Behavioural/Visitor/AnimalVisitor/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://stackoverflow.com/a/255300/225052 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | class Operation; 9 | 10 | class Animal { 11 | public: 12 | virtual void letsDo( Operation* op ) = 0; 13 | }; 14 | 15 | class Cat; 16 | class Dog; 17 | 18 | class Operation { 19 | public: 20 | virtual void catOperation( Cat* cat ) = 0; 21 | virtual void dogOperation( Dog* dog ) = 0; 22 | }; 23 | 24 | class Sound : public Operation { 25 | public: 26 | void dogOperation(Dog* dog ) { 27 | cout << "woof!" << endl; 28 | } 29 | 30 | void catOperation(Cat* cat ) { 31 | cout << "meow!" << endl; 32 | } 33 | }; 34 | 35 | class Dog : public Animal { 36 | public: 37 | void letsDo( Operation* op ) { 38 | op->dogOperation( this ); 39 | } 40 | }; 41 | 42 | class Cat : public Animal { 43 | public: 44 | void letsDo( Operation* op ) { 45 | op->catOperation( this ); 46 | } 47 | }; 48 | 49 | int main() { 50 | 51 | Cat* cat = new Cat(); 52 | Sound* sound = new Sound(); 53 | cat->letsDo( sound ); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /Structural/README.md: -------------------------------------------------------------------------------- 1 | # Structural Patterns 2 |
3 | - [Adapter](Adapter): یک واسط را به واسط مورد نظر کلاینت تبدیل می‌کند و اجازه می‌دهد تا کلاس‌ها با اینترفیس‌های متفاوت و ناسازگار با یکدیگر کار کنند. 4 | 5 | - [Bridge](Bridge): لایهٔ انتزاع را از لایهٔ پیاده‌سازی جدا می‌کند، بنابراین دو کلاس می‌توانند مستقلاً تغییر کنند. 6 | 7 | - [Composite](Composite): اشیاء را درون ساختار درختی ترکیب می‌کند تا سسله-مراتب جز-کل را ارائه کند. الگوی کامپوزت به کارخواه‌ها اجازه می‌دهد تا با اشیاء تکی و با اشیائی که ترکیبی از اشیاء هستند، به یک صورت رفتار کند. 8 | 9 | - [Decorator](Decorator): وظایف و قابلیت‌های بیشتری را به صورت داینامیک به شیء اضافه می‌کند. دکوریتورها برای توسعهٔ رفتارها و قابلیت‌ها روش انعطاف‌پذیر جایزینی را به جای زیرکلاس‌سازی ارائه می‌دهند. 10 | 11 | - [Facade](Facade): واسط یکپارچه‌ای را برای مجموعه‌ای از واسط‌ها در زیر سیستم، ارائه می‌دهد. این الگو واسط سطح-بالاتری را تعریف می‌کند که استفاده از زیرسیستم را ساده‌تر می‌کند. 12 | 13 | - [Flyweight](Flyweight): استفادهٔ دوبارهٔ بسیاری از اشیاء fine-grain را با اشتراک آن‌ها در سیستم، آسان می‌کند. 14 | 15 | - [Proxy](Proxy): برای کنترل دسترسی به اشیاء، نماینده یا نگهدارنده‌ای برای آن‌ها ارائه می‌کند. 16 | 17 | -------------------------------------------------------------------------------- /Structural/Bridge/TvBridge/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://java.dzone.com/articles/design-patterns-bridge 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Implementor 9 | class TV { 10 | public: 11 | virtual void on() = 0; 12 | virtual void off() = 0; 13 | }; 14 | 15 | // Concrete Implementor 16 | class Sony : public TV { 17 | public: 18 | virtual void on() { 19 | cout << "Sony specifc on" << endl; 20 | } 21 | 22 | virtual void off() { 23 | cout << "Sony specifc off" << endl; 24 | } 25 | }; 26 | 27 | // Concrete Implementor 28 | class Philips : public TV { 29 | public: 30 | virtual void on() { 31 | cout << "Philips specifc on" << endl; 32 | } 33 | 34 | virtual void off() { 35 | cout << "Philips specifc off" << endl; 36 | } 37 | }; 38 | 39 | // Abstraction 40 | class RemoteControl { 41 | public: 42 | RemoteControl( TV* tv ) 43 | :_tv( tv ) { 44 | } 45 | 46 | void on() { 47 | _tv->on(); 48 | } 49 | 50 | void off() { 51 | _tv->off(); 52 | } 53 | private: 54 | TV* _tv; 55 | }; 56 | 57 | int main() { 58 | 59 | RemoteControl* remoteControl = new RemoteControl( new Sony() ); 60 | remoteControl->on(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Structural/Bridge/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Implementor { 5 | public: 6 | virtual void operationImpl() = 0; 7 | }; 8 | 9 | 10 | class Abstraction { 11 | public: 12 | Abstraction( Implementor* implementor ) 13 | :_implementor( implementor ) { 14 | } 15 | 16 | void operation() { 17 | _implementor->operationImpl(); 18 | } 19 | protected: 20 | Implementor* _implementor; 21 | }; 22 | 23 | class ConcreteImplementorA : public Implementor { 24 | public: 25 | virtual void operationImpl() { 26 | cout << "Implementation by ConcreteImplementorA" << endl; 27 | } 28 | }; 29 | 30 | class ConcreteImplementorB : public Implementor { 31 | public: 32 | virtual void operationImpl() { 33 | cout << "Implementation by ConcreteImplementorB" << endl; 34 | } 35 | }; 36 | 37 | 38 | int main() { 39 | 40 | ConcreteImplementorA* implementorA = new ConcreteImplementorA(); 41 | Abstraction* abstraction1 = new Abstraction( implementorA ); 42 | abstraction1->operation(); 43 | 44 | ConcreteImplementorB* implementorB = new ConcreteImplementorB(); 45 | Abstraction* abstraction2 = new Abstraction( implementorB ); 46 | abstraction2->operation(); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Structural/Decorator/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.cppblog.com/converse/archive/2006/07/25/10465.html 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | class Component { 9 | public: 10 | virtual void operation() = 0; 11 | }; 12 | 13 | class Decorator : public Component { 14 | public: 15 | Decorator( Component* component ) 16 | :_component( component ) { 17 | } 18 | protected: 19 | Component* _component; 20 | }; 21 | 22 | class ConcreteComponent : public Component { 23 | public: 24 | virtual void operation() { 25 | cout << "operation of ConcreteComponent" << endl; 26 | } 27 | }; 28 | 29 | class ConcreteDecorator : public Decorator { 30 | public: 31 | ConcreteDecorator( Component* component ) 32 | :Decorator( component ) { 33 | } 34 | 35 | virtual void operation() { 36 | _component->operation(); 37 | addedBehavior(); 38 | } 39 | private: 40 | void addedBehavior() { 41 | cout << "addedBehavior of ConcreteDecorator" << endl; 42 | } 43 | }; 44 | 45 | 46 | int main() { 47 | 48 | Component* component = new ConcreteComponent(); 49 | 50 | Decorator* decorator = new ConcreteDecorator( component ); 51 | decorator->operation(); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Structural/Facade/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class SubSystemA { 5 | public: 6 | void MethodA() { 7 | cout << "SubSystemA.MethodA" << endl; 8 | } 9 | }; 10 | 11 | class SubSystemB { 12 | public: 13 | void MethodB() { 14 | cout << "SubSystemB MethodB" << endl; 15 | } 16 | }; 17 | 18 | class SubSystemC { 19 | public: 20 | void MethodC() { 21 | cout << "SubSystemC MethodC" << endl; 22 | } 23 | }; 24 | 25 | 26 | class Facade { 27 | private: 28 | SubSystemA* subSystemA; 29 | SubSystemB* subSystemB; 30 | SubSystemC* subSystemC; 31 | public: 32 | Facade() { 33 | subSystemA = new SubSystemA(); 34 | subSystemB = new SubSystemB(); 35 | subSystemC = new SubSystemC(); 36 | } 37 | 38 | void MethodOne() { 39 | cout << "*** Facade.MethodOne ***" << endl; 40 | subSystemA->MethodA(); 41 | subSystemB->MethodB(); 42 | subSystemC->MethodC(); 43 | } 44 | 45 | void MethodTwo() { 46 | cout << "*** Facade.MethodTwo ***" << endl; 47 | subSystemC->MethodC(); 48 | subSystemA->MethodA(); 49 | } 50 | 51 | }; 52 | int main() { 53 | 54 | Facade* facade = new Facade(); 55 | 56 | facade->MethodOne(); 57 | facade->MethodTwo(); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Behavioural/TemplateMethod/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class AbstractClass { 5 | public: 6 | void TemplateMethod() { 7 | PrimitiveOperation1(); 8 | PrimitiveOperation2(); 9 | } 10 | protected: 11 | virtual void PrimitiveOperation1() = 0; 12 | virtual void PrimitiveOperation2() = 0; 13 | }; 14 | 15 | class ConcreteClass1 : public AbstractClass { 16 | protected: 17 | virtual void PrimitiveOperation1() { 18 | cout << "PrimitiveOperation1 by ConcreteClass1" << endl; 19 | } 20 | virtual void PrimitiveOperation2() { 21 | cout << "PrimitiveOperation2 by ConcreteClass1" << endl; 22 | } 23 | }; 24 | 25 | class ConcreteClass2 : public AbstractClass { 26 | protected: 27 | virtual void PrimitiveOperation1() { 28 | cout << "PrimitiveOperation1 by ConcreteClass2" << endl; 29 | } 30 | virtual void PrimitiveOperation2() { 31 | cout << "PrimitiveOperation2 by ConcreteClass2" << endl; 32 | } 33 | }; 34 | 35 | 36 | 37 | int main (int argc, char const* argv[]) { 38 | 39 | AbstractClass* concreteClass = new ConcreteClass1(); 40 | concreteClass->TemplateMethod(); 41 | 42 | concreteClass = new ConcreteClass2(); 43 | concreteClass->TemplateMethod(); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Behavioural/Strategy/Classic/C++/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Strategy { 5 | public: 6 | virtual void AlgorithmInterface() = 0; 7 | }; 8 | 9 | 10 | class ConcreteStrategyA : public Strategy { 11 | public: 12 | virtual void AlgorithmInterface() { 13 | cout << "AlgorithmInterface implemented by ConcreteStrategyA\n" << endl; 14 | } 15 | }; 16 | 17 | 18 | class ConcreteStrategyB : public Strategy { 19 | public: 20 | virtual void AlgorithmInterface() { 21 | cout << "AlgorithmInterface implemented by ConcreteStrategyB\n" << endl; 22 | } 23 | }; 24 | 25 | class Context { 26 | public: 27 | Context(Strategy* strategy) 28 | : _strategy(strategy) { 29 | } 30 | 31 | void changeStrategy(Strategy* strategy) { 32 | _strategy = strategy; 33 | } 34 | 35 | void ContextInterface() { 36 | if ( NULL != _strategy) { 37 | _strategy->AlgorithmInterface(); 38 | } 39 | } 40 | private: 41 | Strategy* _strategy; 42 | }; 43 | 44 | 45 | 46 | int main (int argc, char const* argv[]) { 47 | 48 | Context* context = new Context(new ConcreteStrategyA()); 49 | context->ContextInterface(); 50 | context->changeStrategy(new ConcreteStrategyB()); 51 | context->ContextInterface(); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Behavioural/Interpreter/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Ported to C++ from http://www.dofactory.com/Patterns/PatternInterpreter.aspx 3 | */ 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Context { 10 | 11 | }; 12 | 13 | 14 | class AbstractExpression { 15 | public: 16 | virtual void interpret( Context* context ) = 0; 17 | }; 18 | 19 | class TerminalExpression : public AbstractExpression { 20 | public: 21 | virtual void interpret( Context* context ) { 22 | cout << "Called Terminal.interpret()" << endl; 23 | } 24 | }; 25 | 26 | class NoneterminalExpression : public AbstractExpression { 27 | public: 28 | virtual void interpret( Context* context ) { 29 | cout << "Called NonTerminal.interpret()" << endl; 30 | } 31 | }; 32 | 33 | 34 | int main() { 35 | 36 | Context* context = new Context(); 37 | 38 | vector list; 39 | 40 | list.push_back( new TerminalExpression() ); 41 | list.push_back( new NoneterminalExpression() ); 42 | list.push_back( new TerminalExpression() ); 43 | list.push_back( new TerminalExpression() ); 44 | 45 | for ( vector::iterator it = list.begin(); 46 | it != list.end(); 47 | ++it ) { 48 | (*it)->interpret(context); 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Behavioural/State/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class State; 5 | class Context; 6 | 7 | class State { 8 | public: 9 | virtual void handle( Context* context ) = 0; 10 | }; 11 | 12 | class Context { 13 | public: 14 | Context( State* state ) 15 | :_state( state ) { 16 | } 17 | 18 | void request() { 19 | _state->handle( this ); 20 | } 21 | 22 | void changeState( State* state ) { 23 | _state = state; 24 | } 25 | 26 | private: 27 | State* _state; 28 | }; 29 | 30 | 31 | class ConcreteStateA : public State { 32 | public: 33 | void handle( Context* context ); 34 | }; 35 | 36 | 37 | class ConcreteStateB : public State { 38 | public: 39 | void handle( Context* context ); 40 | }; 41 | 42 | void ConcreteStateA::handle( Context* context ) { 43 | cout << "Handle by ConcreteStateA" << endl; 44 | context->changeState( new ConcreteStateB() ); 45 | } 46 | 47 | 48 | void ConcreteStateB::handle( Context* context ) { 49 | cout << "Handle by ConcreteStateB" << endl; 50 | context->changeState( new ConcreteStateA() ); 51 | } 52 | 53 | 54 | int main() { 55 | 56 | State* state = new ConcreteStateA(); 57 | Context* context = new Context( state ); 58 | context->request(); 59 | context->request(); 60 | context->request(); 61 | context->request(); 62 | context->request(); 63 | } 64 | -------------------------------------------------------------------------------- /Behavioural/ChainOfResponsibility/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.cppblog.com/converse/archive/2006/07/28/10663.html 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | class Handler { 9 | public: 10 | Handler( Handler* successor = NULL ) 11 | :_successor( successor ) { 12 | } 13 | 14 | virtual void handleRequest() = 0; 15 | protected: 16 | Handler* _successor; 17 | }; 18 | 19 | class ConcreteHandler1 : public Handler { 20 | public: 21 | ConcreteHandler1( Handler* successor = NULL ) 22 | :Handler( successor ) { 23 | } 24 | 25 | virtual void handleRequest() { 26 | if ( NULL != _successor ) { 27 | _successor->handleRequest(); 28 | } else { 29 | cout << "handleRequest by ConcreteHandler1" << endl; 30 | } 31 | } 32 | }; 33 | 34 | class ConcreteHandler2 : public Handler { 35 | public: 36 | ConcreteHandler2( Handler* successor = NULL ) 37 | :Handler( successor ) { 38 | } 39 | virtual void handleRequest() { 40 | if ( NULL != _successor ) { 41 | _successor->handleRequest(); 42 | } else { 43 | cout << "handleRequest by ConcreteHandler2" << endl; 44 | } 45 | } 46 | }; 47 | 48 | int main() { 49 | 50 | Handler* handler1 = new ConcreteHandler1(); 51 | Handler* handler2 = new ConcreteHandler2( handler1 ); 52 | 53 | handler2->handleRequest(); 54 | 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Behavioural/State/README.md: -------------------------------------------------------------------------------- 1 |
2 | #هدف 3 | به شیء این اجازه را می‌دهد که وقتی وضعیت درونی‌اش تغییر کرد، رفتارش را تغییر دهد. به نظر می‌رسد که شیء کلاس خود را عوض می‌کند. 4 | 5 | # ساختار 6 | ![State Pattern UML](http://i.imgur.com/fSlH2TY.png) 7 | 8 | # اجزاء الگو 9 | - Context 10 | - State 11 | - ConcreteState 12 | 13 | # نکات طراحی 14 | زمانی از این الگو استفاده کنید که 15 | - رفتار شیء وابسته به وضعیت‌اش متغییر است و شیء بنا به وضعیت خود که در زمان اجرا مشخص می‌شود، تغییر حالتش متفاوت است. 16 | - رفتارهای شیء توسط تعداد بسیار زیادی از متغییرهای شرطی تعیین می‌شود (اگر-آنگاه‌های زیاد). 17 | 18 | # مثال (تغییر اوقات شبانه‌روز) 19 | خورشید در گردش حول زمین در وضعیت‌های متفاوتی قرار می‌گیرد: بادمداد، چاشت، شامگاه و شبانگاه. که کد کارخواه آن به صورت زیر است: 20 |
21 | ```c++ 22 | Sun* sun = new Sun( new Bamdad() ); 23 | sun->afterSixHours(); 24 | cout << sun->getState() << endl; 25 | 26 | sun->afterSixHours(); 27 | cout << sun->getState() << endl; 28 | 29 | sun->afterSixHours(); 30 | cout << sun->getState() << endl; 31 | ``` 32 |
33 | 34 | 35 | # مثال 36 | - برای طراحی Finite State Machine می‌توان از این الگو استفاه کرد. 37 | 38 | # مثال‌های واقعی 39 |
40 | - javax.faces.lifecycle.LifeCycle#execute() (controlled by FacesServlet, the behaviour is dependent on current phase (state) of JSF lifecycle) 41 | -------------------------------------------------------------------------------- /Creational/README.md: -------------------------------------------------------------------------------- 1 |
2 | # Creational Patterns 3 | 4 | - [Abstract Factory](AbstractFactory): بدون مشخص کردن کلاس‌های کانکرت، واسطی برای ساخت خانواده‌ای از اشیاء وابسته یا مرتبط با یکدیگر فراهم می‌کند. 5 | 6 | - [Builder](Builder): روند ساخت یک شیء پیچیده را از نمایش آن جدا می‌کند به طوری که یک روند ساخت مشترک می‌تواند برای ساخت انوع بازنمایی‌ها به کار گرفته شود. 7 | 8 | - [Factory Method](FactoryMethod): واسطی برای ساخت اشیاء ایجاد می‌کند، اما به زیرکلاس‌ها اجازه می‌دهد که تصمیم بگیرند که چه کلاسی را نمونه‌سازی کنند. این الگو اجازه می‌دهد تا نمونه‌برداری کلاس، به زیرکلاس‌ها معوق شود. 9 | 10 | - [Prototype](Prototype): انواع اشیائی که باید ساخته شوند را با استفاده از یک نمونهٔ اولیه، مشخص می‌کند و اشیاء جدید را با کپی کردن این نمونهٔ اولیه تولید می‌کند. 11 | 12 | - [Singleton](Singleton): تضمین می‌کند که کلاس تنها یک نمونه داشته باشد و دسترسی سراسری برای آن فراهم می‌کند. 13 | 14 | 15 | # فرق بین Abstract Factory و Factory Method چیست؟ 16 | الگوی Abstract Factory 17 | - اجازهٔ تعریف خانواده‌ای از اشیاء را می‌دهد و پیاده‌سازی ساخت این اشیاء را از کارخواه مخفی می‌کند. 18 | - متدهای Abstract Factory همانند متد فکتوری پیاده‌سازی می‌شود. 19 | 20 | الگوی Factory Method 21 | - اجازهٔ تعریف چگونگی ساخت یک نوع شیء را می‌دهد و پیاده‌سازی ساخت این شیء را از کارخواه مخفی می‌کند. 22 | - الگوی طراحی Factory Method نسخهٔ ساده‌شده‌ای از Abstract Factoryی‌ست. 23 | -------------------------------------------------------------------------------- /Creational/SimpleFactory/SimplePizzaFactory/C++/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Pizza {}; 6 | class CheesePizza : public Pizza { 7 | public: 8 | CheesePizza() { 9 | cout << "CheesePizza is created" << endl; 10 | } 11 | }; 12 | class PepperoniPizza : public Pizza { 13 | public: 14 | PepperoniPizza() { 15 | cout << "PepperoniPizza is created" << endl; 16 | } 17 | }; 18 | class ClamPizza : public Pizza { 19 | public: 20 | ClamPizza() { 21 | cout << "ClamPizza is created" << endl; 22 | } 23 | }; 24 | class VeggiePizza : public Pizza { 25 | public: 26 | VeggiePizza() { 27 | cout << "VeggiePizza is created" << endl; 28 | } 29 | }; 30 | 31 | class SimplePizzaFactory { 32 | public: 33 | Pizza* createPizza( const char* type ) { 34 | if ( strcmp( type, "cheese" ) == 0 ) { 35 | return new CheesePizza(); 36 | } else if ( strcmp( type, "pepperoni" ) == 0 ) { 37 | return new PepperoniPizza(); 38 | } else if ( strcmp( type, "clam" ) == 0 ) { 39 | return new ClamPizza(); 40 | } else if ( strcmp( type, "veggie" ) == 0 ) { 41 | return new VeggiePizza(); 42 | } 43 | } 44 | }; 45 | 46 | 47 | int main (int argc, char const* argv[]) { 48 | 49 | SimplePizzaFactory* factory = new SimplePizzaFactory(); 50 | Pizza* pizza = factory->createPizza("clam"); 51 | 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Structural/Proxy/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | برای کنترل دسترسی به اشیاء، نماینده یا نگهدارنده‌ای برای آن‌ها ارائه می‌کند. 4 | 5 | # ساختار 6 | ![Proxy Pattern UML](http://javaobsession.files.wordpress.com/2010/07/proxy-diagram.png) 7 | 8 | # اجزاء الگو 9 | - Proxy: به شیء واقعی اشاره دارد، هر گاه درخواستی ارسال شود، شیء واقعی را صدا می‌زند. 10 | - Subject: یک واسط مشترک برای RealSubject و Proxy تعریف می‌کند. 11 | - RealSubject: شیء واقعی را تعریف می‌کند. 12 | 13 | # نکات طراحی 14 | زمانی از این الگو استفاده کنید که 15 | - پراکسی دور (Remote Proxy): نیاز به بازنمایی محلی یک شیء دور که در فضای آدرس دیگری قرار دارد، دارید. 16 | - پراکسی مجازی (Virtual Proxy): نیاز به ارائهٔ روشی برای ساخت اشیاء هزینه‌بر، به صورت بنا-به-درخواست (on-demand) هستید. 17 | - پراکسی محافظ (Protection Proxy): نیاز به کنترل دسترسی به اشیاء دارید. 18 | - اشاره‌گر هوشمند (Smart Reference): اقدامات اضافی تنها زمانی باید اجرا شوند که شیء دستیابی شود. 19 | 20 | # مثال (پراکسی مجازی) 21 | فرض کنید یک ویرایشگر تصویر دارید، و تصاویر حجم بالایی دارند. کاربر چندین تصویر را همزمان برای باز شدن در ویرایشگر انتخاب می‌کند، به خاطر اینکه در هنگام باز شدن ویرایشگر لازم نیست که تمام عکس‌ها در حافظه بار شوند، می‌توانیم بار شدن عکس‌ها در حافظه را تا زمانی که نیاز واقعی به تصاویر نداریم به معوق کنیم. 22 | 23 | # مثال‌های واقعی 24 |
25 | - java.lang.reflect.Proxy 26 | - java.rmi.*, the whole API actually. 27 | -------------------------------------------------------------------------------- /Creational/Builder/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.cppblog.com/converse/archive/2006/07/21/10305.html 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | class Builder { 9 | public: 10 | virtual void buildPartA() = 0; 11 | virtual void buildPartB() = 0; 12 | }; 13 | 14 | class ConcreteBuilder1 : public Builder { 15 | public: 16 | virtual void buildPartA() { 17 | cout << "buildPartA by ConcreteBuilder1" << endl; 18 | } 19 | 20 | virtual void buildPartB() { 21 | cout << "buildPartB by ConcreteBuilder1" << endl; 22 | } 23 | }; 24 | 25 | class ConcreteBuilder2 : public Builder { 26 | virtual void buildPartA() { 27 | cout << "buildPartA by ConcreteBuilder2" << endl; 28 | } 29 | virtual void buildPartB() { 30 | cout << "buildPartB by ConcreteBuilder2" << endl; 31 | } 32 | }; 33 | 34 | class Director { 35 | public: 36 | Director( Builder* builder ) 37 | :_builder( builder ) { 38 | } 39 | 40 | void construct() { 41 | _builder->buildPartA(); 42 | _builder->buildPartB(); 43 | } 44 | 45 | private: 46 | Builder* _builder; 47 | }; 48 | 49 | int main() { 50 | 51 | Builder* builder1 = new ConcreteBuilder1(); 52 | Director* director1 = new Director( builder1 ); 53 | director1->construct(); 54 | 55 | Builder* builder2 = new ConcreteBuilder2(); 56 | Director* director2 = new Director( builder2 ); 57 | director2->construct(); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Structural/Decorator/Java/TestDecorator.java: -------------------------------------------------------------------------------- 1 | interface Icecream { 2 | public String makeIcecream(); 3 | } 4 | 5 | class SimpleIcecream implements Icecream { 6 | public String makeIcecream() { 7 | return "Base Icecream"; 8 | } 9 | } 10 | 11 | abstract class IcecreamDecorator implements Icecream { 12 | protected Icecream specialIcecream; 13 | 14 | public IcecreamDecorator( Icecream specialIcecream ) { 15 | this.specialIcecream = specialIcecream; 16 | } 17 | 18 | public String makeIcecream() { 19 | return specialIcecream.makeIcecream(); 20 | } 21 | } 22 | 23 | class NuttyDecorator extends IcecreamDecorator { 24 | public NuttyDecorator( Icecream specialIcecream ) { 25 | super( specialIcecream ); 26 | } 27 | 28 | public String makeIcecream() { 29 | return specialIcecream.makeIcecream() + addNuts(); 30 | } 31 | 32 | private String addNuts() { 33 | return " + cruncy nuts"; 34 | } 35 | } 36 | 37 | class HoneyDecorator extends IcecreamDecorator { 38 | public HoneyDecorator( Icecream specialIcecream ) { 39 | super( specialIcecream ); 40 | } 41 | 42 | public String makeIcecream() { 43 | return specialIcecream.makeIcecream() + addHoney(); 44 | } 45 | 46 | private String addHoney() { 47 | return " + sweet honey"; 48 | } 49 | } 50 | 51 | public class TestDecorator { 52 | public static void main(String args[]) { 53 | Icecream icecream = new HoneyDecorator( new NuttyDecorator( new SimpleIcecream() ) ); 54 | System.out.println( icecream.makeIcecream() ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Architecture/MVC/Javascript/HelloWorld/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Behavioural/TemplateMethod/DocumentGenerator/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class DocumentGenerator { 5 | protected: 6 | virtual void generateHeader() = 0; 7 | virtual void generateBody() = 0; 8 | virtual void generateDetails() = 0; 9 | public: 10 | void generateDocument() { 11 | generateHeader(); 12 | generateBody(); 13 | generateDetails(); 14 | } 15 | }; 16 | 17 | class HtmlGenerator : public DocumentGenerator { 18 | protected: 19 | virtual void generateHeader() { 20 | cout << "Header of HTML Document is created" << endl; 21 | } 22 | 23 | virtual void generateBody() { 24 | cout << "Body of HTML Document is created" << endl; 25 | } 26 | 27 | virtual void generateDetails() { 28 | cout << "Details of HTML Document is created" << endl; 29 | } 30 | }; 31 | 32 | 33 | class PDFGenerator : public DocumentGenerator { 34 | protected: 35 | virtual void generateHeader() { 36 | cout << "Header of PDF Document is created" << endl; 37 | } 38 | 39 | virtual void generateBody() { 40 | cout << "Body of PDF Document is created" << endl; 41 | } 42 | 43 | virtual void generateDetails() { 44 | cout << "Details of PDF Document is created" << endl; 45 | } 46 | }; 47 | 48 | 49 | int main (int argc, char const* argv[]) { 50 | 51 | DocumentGenerator* generator; 52 | 53 | generator = new PDFGenerator(); 54 | generator->generateDocument(); 55 | 56 | generator = new HtmlGenerator(); 57 | generator->generateDocument(); 58 | 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Behavioural/Iterator/README.md: -------------------------------------------------------------------------------- 1 |
2 | # تعریف 3 | روشی برای دستری به عناصر یک شیء اگریگیت فراهم می‌کند بدون اینکه اصول پیاده‌سازی و ساختمان دادهٔ لایهٔ زیرین اگریگیت را نمایش دهد. 4 | 5 | # ساختار 6 | ![Iterator UML](http://javaobsession.files.wordpress.com/2010/07/iterator-pattern.png) 7 | 8 | 9 | # اجزاء الگو 10 | - Iterator 11 | - ConcreteIterator 12 | - Aggregate 13 | - ConcreteAggregatge 14 | 15 | # نکات طراحی 16 | زمانی از این الگو استفاده کنید که 17 | - نیاز دارید تا روش یکپارچه‌ای را برای پیمایش عناصر یک مجموعه (کالکشن) فراهم کنید بدون این که ساختمان داده‌های کالکشن را افشا کنید. 18 | - نیاز به واسط مشترکی برای پیمایش ساختمان داده‌های تجمعی مختلف دارید. 19 | - وقتی کالکشن‌ها و کانتینرهای متفاوتی داشته باشیم: list، vector، array، arrayList، set, multiset, queue, map, multimap و ... می‌توانیم با استفاده از Iterator یک اینترفیس یکسان برای دسترسی به محتوای این کانتینرها بنویسم. در این الگوی طراحی برای دسترسی به داده‌های کانتینرها لازم نیست از ساختمان داده‌های تک تک کانتینرها سردر بیاوریم. 20 | 21 | # مثال‌های واقعی 22 |
23 | - All implementations of java.util.Iterator (thus among others also java.util.Scanner!). 24 | - All implementations of java.util.Enumeration 25 |
26 | 27 | # اطلاعات بیشتر 28 |
29 | 1. java.util.Iterator, java.util.ArrayList 30 | 2. [Java Iterator](http://javapapers.com/core-java/java-iterator/) 31 | 3. [Understanding and Implementing the Iterator Pattern in C# and C++](http://www.codeproject.com/Articles/362986/Understanding-and-Implementing-the-Iterator-Patter) 32 | -------------------------------------------------------------------------------- /Creational/FactoryMethod/MobileFactoryMethod/C++/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Mobile {}; 6 | class N900 : public Mobile { 7 | public: 8 | N900() { 9 | cout << "N900 is created" << endl; 10 | } 11 | }; 12 | class N95 : public Mobile { 13 | public: 14 | N95() { 15 | cout << "N95 is created" << endl; 16 | } 17 | }; 18 | 19 | class Atrix : public Mobile { 20 | public: 21 | Atrix() { 22 | cout << "Atrix is created" << endl; 23 | } 24 | }; 25 | 26 | class A1200 : public Mobile { 27 | public: 28 | A1200() { 29 | cout << "A1200 is created" << endl; 30 | } 31 | }; 32 | 33 | class Factory { 34 | public: 35 | virtual Mobile* createMobile(const char* name) = 0; 36 | }; 37 | 38 | class NokiaFactory : public Factory { 39 | Mobile* createMobile(const char* name) { 40 | if (strcmp( name, "N900" ) == 0 ) { 41 | return new N900(); 42 | } else if ( strcmp( name, "N95" ) == 0 ) { 43 | return new N95(); 44 | } 45 | } 46 | }; 47 | 48 | class MotorolaFactory : public Factory { 49 | Mobile* createMobile(const char* name) { 50 | if (strcmp( name, "Atrix" ) == 0 ) { 51 | return new Atrix(); 52 | } else if ( strcmp( name, "A1200" ) == 0 ) { 53 | return new A1200(); 54 | } 55 | } 56 | }; 57 | 58 | 59 | int main (int argc, char const* argv[]) { 60 | 61 | Factory* factory = new NokiaFactory(); 62 | Mobile* mobile = factory->createMobile("N900"); 63 | 64 | factory = new MotorolaFactory(); 65 | mobile = factory->createMobile("A1200"); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Behavioural/Memento/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.cppblog.com/converse/archive/2006/08/09/11063.html 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | class Memento { 9 | private: 10 | friend class Orginator; 11 | Memento( const char* & state ) 12 | :_state( state ) { 13 | } 14 | 15 | void setState( const char* & state ) { 16 | _state = state; 17 | } 18 | 19 | const char* getState() { 20 | return _state; 21 | } 22 | 23 | const char* _state; 24 | }; 25 | 26 | 27 | 28 | class Orginator { 29 | public: 30 | Orginator( const char* & state ) 31 | :_state( state ) { 32 | } 33 | 34 | Memento* createMemento() { 35 | return new Memento( _state ); 36 | } 37 | 38 | const char* getState() { 39 | return _state; 40 | } 41 | 42 | void setState( const char* & state ) { 43 | _state = state; 44 | } 45 | 46 | void restorState( Memento* memento ) { 47 | if ( NULL != memento ) { 48 | _state = memento->getState(); 49 | } 50 | } 51 | 52 | void printState() { 53 | cout << "State = " << _state << endl; 54 | } 55 | 56 | private: 57 | const char* _state; 58 | }; 59 | 60 | int main() { 61 | 62 | const char* oldState = "Old state"; 63 | Orginator* orginator = new Orginator( oldState ); 64 | orginator->printState(); 65 | 66 | Memento* memento = orginator->createMemento(); 67 | 68 | const char* newState = "New State"; 69 | orginator->setState( newState ); 70 | orginator->printState(); 71 | 72 | orginator->restorState( memento ); 73 | orginator->printState(); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Behavioural/Command/StockAgent/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://login2win.blogspot.com/2011/06/command-pattern.html 3 | */ 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // Command interface 9 | class Command { 10 | public: 11 | virtual void execute() = 0; 12 | }; 13 | 14 | // Receiver 15 | class StockTrade { 16 | public: 17 | void buy() { cout << "Buy Stock" << endl; } 18 | void sell() { cout << "Sell Stock" << endl; } 19 | }; 20 | 21 | // Concrete command 1 22 | class BuyOrder : public Command { 23 | private: 24 | StockTrade* _stock; 25 | public: 26 | BuyOrder(StockTrade* stock) 27 | :_stock( stock ) { 28 | } 29 | 30 | void execute() { 31 | _stock->buy(); 32 | } 33 | }; 34 | 35 | // Concrete command 2 36 | class SellOrder : public Command { 37 | private: 38 | StockTrade* _stock; 39 | public: 40 | SellOrder(StockTrade* stock) { 41 | _stock = stock; 42 | } 43 | void execute() { 44 | _stock->sell(); 45 | } 46 | }; 47 | 48 | 49 | // Invoker 50 | class StockAgent { 51 | public: 52 | void order( Command* command ) { 53 | commandList.push_back( command ); 54 | command->execute(); 55 | } 56 | private: 57 | vector commandList; 58 | }; 59 | 60 | 61 | int main (int argc, char const* argv[]) { 62 | 63 | StockAgent* agent = new StockAgent(); 64 | 65 | StockTrade* stock = new StockTrade(); 66 | BuyOrder* buy1 = new BuyOrder( stock ); 67 | BuyOrder* buy2 = new BuyOrder( stock ); 68 | SellOrder* sell1 = new SellOrder( stock ); 69 | 70 | agent->order(buy1); 71 | agent->order(buy2); 72 | agent->order(sell1); 73 | 74 | 75 | 76 | 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractMobileFactory/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class SmartPhone {}; 5 | class NoneSmartPhone {}; 6 | 7 | class Nokia1100 : public NoneSmartPhone { 8 | public: 9 | Nokia1100() { 10 | cout << "Nokia1100 is created" << endl; 11 | } 12 | }; 13 | 14 | class NokiaN950 : public SmartPhone { 15 | public: 16 | NokiaN950() { 17 | cout << "NokiaN950 is created" << endl; 18 | } 19 | }; 20 | 21 | class MotorolaAtrix4G : public SmartPhone { 22 | public: 23 | MotorolaAtrix4G() { 24 | cout << "Atrix4G is created" << endl; 25 | } 26 | }; 27 | 28 | class MotorolaA1200 : public NoneSmartPhone { 29 | public: 30 | MotorolaA1200() { 31 | cout << "A1200 is created" << endl; 32 | } 33 | }; 34 | 35 | class AbstractMobileFactory { 36 | public: 37 | virtual SmartPhone* createSmartPhone() = 0; 38 | virtual NoneSmartPhone* createNoneSmartPhone() = 0; 39 | }; 40 | 41 | class NokiaFactory : public AbstractMobileFactory { 42 | public: 43 | SmartPhone* createSmartPhone() { 44 | return new NokiaN950(); 45 | } 46 | 47 | NoneSmartPhone* createNoneSmartPhone() { 48 | return new Nokia1100(); 49 | } 50 | }; 51 | 52 | class MotorolaFactory : public AbstractMobileFactory { 53 | public: 54 | SmartPhone* createSmartPhone() { 55 | return new MotorolaAtrix4G(); 56 | } 57 | 58 | NoneSmartPhone* createNoneSmartPhone() { 59 | return new MotorolaA1200(); 60 | } 61 | }; 62 | 63 | 64 | int main (int argc, char const* argv[]) { 65 | 66 | AbstractMobileFactory* factory = new NokiaFactory(); 67 | SmartPhone* smartPhone = factory->createSmartPhone(); 68 | 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Structural/Adapter/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | یک واسط را به واسط مورد نظر کلاینت تبدیل می‌کند و اجازه می‌دهد تا کلاس‌ها با اینترفیس‌های متفاوت و ناسازگار با یکدیگر کار کنند. 4 | 5 | # ساختار 6 | # نسخهٔ کلاس (وراثت چندگانه) 7 | ![Adpater (Class Version)](http://javaobsession.files.wordpress.com/2010/07/adapter-pattern-class1.png) 8 | 9 | # نسخهٔ شیء (کامپوزیشن) 10 | ![Adapter (Object Version)](http://javaobsession.files.wordpress.com/2010/07/adapter-pattern-object.png) 11 | 12 | # نکات طراحی 13 | راه‌های پیاده‌سازی: 14 | 15 | - چندوراثتی (Multiple Inheritance): کلاس Adapter، رابط Adaptee و Target را پیاده‌سازی می‌کند. (در جاوا از implement می‌توان به چند وراثتی دست یافت) 16 | - ترکیب شی (Object Composition)؛ کلاس Adapter، رابط Target را پیاده‌سازی می‌کند و درخواست‌های Target را برای Adaptee ترجمه می‌کند. 17 | 18 | # اجزاء الگو 19 | ## Target 20 | واسطی‌ست (اینترفیس) که کلاینت از آن استفاده می‌کند. 21 | 22 | ## Client 23 | شیئ‌ای‌ست که با اشیاء‌ای که با Target Interface مطابقت دارند، همکاری می‌کند. 24 | 25 | ## Adaptee 26 | واسطی‌ست که با واسطِ درخواستی کلاینت ما ناسازگار است و قرار است توسط Adapter به واسط درخواستی کلاینت سازگار شود. 27 | 28 | ## Adapter 29 | یک رابط را به رابط دیگر (متناسب با درخواست کلاینت) تبدیل می‌کند. درخواست کلاینت را می‌گیرد، و آن را برای Adaptee Interface ترجمه می‌کند. 30 | 31 | این کلاس، رابط Target را پیاده‌سازی می‌کند 32 | 33 | # مثال‌های واقعی 34 |
35 | - java.util.Arrays#asList() 36 | - java.io.InputStreamReader(InputStream) (returns a Reader) 37 | - java.io.OutputStreamWriter(OutputStream) (returns a Writer) 38 | - javax.xml.bind.annotation.adapters.XmlAdapter#marshal() and #unmarshal() 39 | 40 | 41 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++-example2/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class AbstractProductA {}; 5 | 6 | class ProductA1 : public AbstractProductA { 7 | public: 8 | ProductA1() { 9 | cout << "Product A of Factory 1 is created" << endl; 10 | } 11 | }; 12 | 13 | class ProductA2 : public AbstractProductA { 14 | public: 15 | ProductA2() { 16 | cout << "Product A of Factory 2 is created" << endl; 17 | } 18 | }; 19 | 20 | class AbstractProductB {}; 21 | 22 | class ProductB1 : public AbstractProductB { 23 | public: 24 | ProductB1() { 25 | cout << "Product B of Factory 1 is created" << endl; 26 | } 27 | }; 28 | 29 | class ProductB2 : public AbstractProductB { 30 | public: 31 | ProductB2() { 32 | cout << "Product B of Factory 2 is created" << endl; 33 | } 34 | }; 35 | 36 | class AbstractFactory { 37 | public: 38 | virtual AbstractProductA* createProductA() = 0; 39 | virtual AbstractProductB* createProductB() = 0; 40 | }; 41 | 42 | class ConcreteFactory1 : public AbstractFactory { 43 | public: 44 | AbstractProductA* createProductA() { 45 | return new ProductA1(); 46 | } 47 | 48 | AbstractProductB* createProductB() { 49 | return new ProductB1(); 50 | } 51 | }; 52 | 53 | class ConcreteFactory2 : public AbstractFactory { 54 | public: 55 | AbstractProductA* createProductA() { 56 | return new ProductA2(); 57 | } 58 | 59 | AbstractProductB* createProductB() { 60 | return new ProductB2(); 61 | } 62 | }; 63 | 64 | int main (int argc, char const* argv[]) { 65 | 66 | AbstractFactory* factory = new ConcreteFactory1(); 67 | AbstractProductA* pa1 = factory->createProductA(); 68 | AbstractProductB* pb1 = factory->createProductB(); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Creational/Prototype/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | انواع اشیائی که باید ساخته شوند را با استفاده از یک نمونهٔ اولیه، مشخص می‌کند و اشیاء جدید را با کپی کردن این نمونهٔ اولیه تولید می‌کند. 4 | 5 | # ساختار 6 | ![Prototype UML](http://javaobsession.files.wordpress.com/2010/07/prototype-pattern1.png) 7 | 8 | # نکات طراحی 9 | از این الگو زمانی استفاده کنید که 10 | - آرایش و ترکیب اشیاء، ساخت اشیاء و همچنین بازنمایی اشیاء باید از سیستم decouple شوند. 11 | - کلاس‌هایی که قرار است نمونه‌سازی شوند، در زمان اجرا مشخص می‌شوند. 12 | - ساخت اولیهٔ هر شیء بسیار هزینه‌بر است. 13 | 14 | # شرح الگو 15 | در این الگو بدون این که نام کلاس اشیاء را بدانیم یا از جزئیات ساخت اشیاء مطلع باشیم با استفاده از کلون کردن آن‌ها را ایجاد می‌کنیم. 16 | 17 | وقتی که ساخت یک شیئ زمان‌بر و هزینه‌بر باشد. بهتر است به جای این که برای تعداد زیادی از اشیاء تمام مراحل ساخت شیئ را طی کنیم، یک پروتوتایپ می‌سازیم سپس از روی آن نمونه‌برداری می‌کنیم و طبق نیازهای خودمان، اشیاء جدید را اصلاح می‌کنیم. 18 | پروتوتایپ: نمونهٔ اولیه، اولین شی‌ای که می‌سازیم و سپس تمامی اشیاء را از روی این شئ می‌سازیم. 19 | 20 | مثال: ساختن انواع اقسام خانه‌ها خیلی زمان‌بر است. همهٔ مراحل ساخت این خانه‌ها هم یکسان است. در نتیجه به جای این که هر دفعه که مشتری خانهٔ خاصی (گلی، خشتی، سیمانی و ...) را طلب کرد. از یک نمونهٔ اولیه (پروتوتایپ) که قبلاً ساخته‌ایم یکی فتوکپی می‌گیریم و سپس متناسب با نیاز مشتری آن را تغییر می‌دهیم و به مشتری تحویل می‌دهیم. اینطوری دیگر لازم نیست تمامی مراحل زمان‌بر ساخت خانه را از اول تکرار کنیم. (DRY) 21 | 22 | # مثال‌های واقعی 23 | - java.lang.Object#clone() (the class has to implement java.lang.Cloneable) 24 | 25 | # بیشتر بخوانید 26 | - http://www.codeproject.com/Articles/42582/Prototype-Design-Pattern 27 | 28 | DRY: Do Not Repeat Yourself 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++/AbstractFactory.hpp: -------------------------------------------------------------------------------- 1 | //source: https://github.com/wxjeacen/DesignPattern.git 2 | 3 | #ifndef ABSTRACTFACTORY_H 4 | #define ABSTRACTFACTORY_H 5 | 6 | class AbstractProductA { 7 | public: 8 | AbstractProductA(){}; 9 | virtual ~AbstractProductA(){}; 10 | }; 11 | 12 | class ConcreateProductA1 13 | :public AbstractProductA { 14 | public: 15 | ConcreateProductA1(); 16 | virtual ~ConcreateProductA1(); 17 | }; 18 | 19 | class ConcreateProductA2 20 | :public AbstractProductA { 21 | public: 22 | ConcreateProductA2(); 23 | virtual ~ConcreateProductA2(); 24 | }; 25 | 26 | class AbstractProductB { 27 | public: 28 | AbstractProductB(){}; 29 | virtual ~AbstractProductB(){}; 30 | }; 31 | 32 | class ConcreateProductB1 33 | :public AbstractProductB { 34 | public: 35 | ConcreateProductB1(); 36 | virtual ~ConcreateProductB1(); 37 | }; 38 | 39 | class ConcreateProductB2 40 | :public AbstractProductB { 41 | public: 42 | ConcreateProductB2(); 43 | virtual ~ConcreateProductB2(); 44 | }; 45 | 46 | class AbstractFactory { 47 | public: 48 | AbstractFactory(){}; 49 | virtual ~AbstractFactory(){}; 50 | 51 | virtual AbstractProductA* CreateProductA() = 0; 52 | virtual AbstractProductB* CreateProductB() = 0; 53 | }; 54 | 55 | class ConcreateFactory1 56 | :public AbstractFactory { 57 | public: 58 | ConcreateFactory1(); 59 | virtual ~ConcreateFactory1(); 60 | 61 | virtual AbstractProductA* CreateProductA(); 62 | virtual AbstractProductB* CreateProductB(); 63 | }; 64 | 65 | class ConcreateFactory2 66 | :public AbstractFactory { 67 | public: 68 | ConcreateFactory2(); 69 | virtual ~ConcreateFactory2(); 70 | 71 | virtual AbstractProductA* CreateProductA(); 72 | virtual AbstractProductB* CreateProductB(); 73 | }; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /Behavioural/Iterator/Classic/C++/2/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Iterator interface 6 | class ChannelIterator { 7 | public: 8 | virtual bool hasNext() = 0; 9 | virtual void next() = 0; 10 | virtual const char* currentItem() = 0; 11 | }; 12 | 13 | 14 | // Aggregate Interface 15 | class TV { 16 | public: 17 | virtual ChannelIterator* getIterator() = 0; 18 | virtual void add(const char*) = 0; 19 | }; 20 | 21 | // Concrete Iterator 22 | class ConcreteChannelIterator : public ChannelIterator { 23 | public: 24 | ConcreteChannelIterator( vector channels ) { 25 | _channels = channels; 26 | _currentPos = 0; 27 | } 28 | 29 | bool hasNext() { 30 | if (_currentPos + 1 < _channels.size() ) { 31 | return true; 32 | } 33 | return false; 34 | } 35 | 36 | void next() { 37 | _currentPos++; 38 | } 39 | 40 | const char* currentItem() { 41 | return _channels[_currentPos]; 42 | } 43 | 44 | private: 45 | vector _channels; 46 | int _currentPos; 47 | }; 48 | 49 | 50 | // Concrete Aggregator 51 | class ConcreteTV : public TV { 52 | public: 53 | ConcreteTV() { 54 | _iterator = new ConcreteChannelIterator( _channels ); 55 | } 56 | 57 | void add( const char* item ) { 58 | _channels.push_back(item); 59 | } 60 | 61 | ChannelIterator* getIterator() { 62 | _iterator = new ConcreteChannelIterator( _channels ); 63 | return _iterator; 64 | } 65 | private: 66 | ChannelIterator* _iterator; 67 | vector _channels; 68 | }; 69 | 70 | 71 | int main() { 72 | 73 | TV* tv = new ConcreteTV(); 74 | tv->add("Channel 1"); 75 | tv->add("Channel 2"); 76 | ChannelIterator* it = tv->getIterator(); 77 | 78 | cout << it->hasNext() << endl; 79 | cout << it->currentItem() << endl; 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /Structural/Bridge/VehicleWorkshopBridge/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://javapapers.com/design-patterns/bridge-design-pattern/ 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | 9 | // Implementor 10 | class Workshop { 11 | public: 12 | virtual void work() = 0; 13 | }; 14 | 15 | // Abstraction 16 | class Vehicle { 17 | public: 18 | Vehicle( Workshop* workshop1, Workshop* workshop2 ) 19 | :_workshop1( workshop1 ), 20 | _workshop2( workshop2 ) { 21 | } 22 | 23 | virtual void manufacture() = 0; 24 | 25 | protected: 26 | Workshop* _workshop1; 27 | Workshop* _workshop2; 28 | }; 29 | 30 | // Concrete implementation 1 31 | class Produce : public Workshop { 32 | public: 33 | virtual void work() { 34 | cout << "Produced"; 35 | } 36 | }; 37 | 38 | // Concrete implementation 2 39 | class Assemple : public Workshop { 40 | public: 41 | virtual void work() { 42 | cout << " Assembled" << endl; 43 | } 44 | }; 45 | 46 | // Refine Abstraction 1 47 | class Car : public Vehicle { 48 | public: 49 | Car( Workshop* workshop1, Workshop* workshop2 ) 50 | :Vehicle(workshop1, workshop2) { 51 | } 52 | 53 | virtual void manufacture() { 54 | cout << "Car "; 55 | _workshop1->work(); 56 | _workshop2->work(); 57 | } 58 | 59 | }; 60 | 61 | // Refine Abstraction 2 62 | class Bike : public Vehicle { 63 | public: 64 | Bike( Workshop* workshop1, Workshop* workshop2 ) 65 | :Vehicle( workshop1, workshop2 ) { 66 | } 67 | 68 | virtual void manufacture() { 69 | cout << "Bike "; 70 | _workshop1->work(); 71 | _workshop2->work(); 72 | } 73 | }; 74 | 75 | int main() { 76 | 77 | Vehicle* vehicle1 = new Car( new Produce(), new Assemple() ); 78 | vehicle1->manufacture(); 79 | 80 | Vehicle* vehicle2 = new Bike( new Produce(), new Assemple() ); 81 | vehicle2->manufacture(); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Structural/Decorator/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | وظایف و قابلیت‌های بیشتری را به صورت داینامیک به شیء اضافه می‌کند. دکوریتورها برای توسعهٔ رفتارها و قابلیت‌ها روش انعطاف‌پذیر جایزینی را به جای زیرکلاس‌سازی ارائه می‌دهند. 4 | 5 | # نام دیگر 6 | Wrapper 7 | 8 | # ساختار 9 | ![Decorator UML](http://javaobsession.files.wordpress.com/2010/07/decorator-pattern.png) 10 | 11 | # نکات طراحی 12 | - انعطاف‌پذیری و تغییر رفتار نمونه‌ها، در زمان اجرا. 13 | - اصل Open-Closed: کلاس‌ها باید برای توسعه و گسترش باز باشند اما برای تغییر بسته. 14 | - کلاس Decorator از aggregation استفاده می‌کند. 15 | 16 | زمانی از این الگو استفاده کنید که 17 | - بدون زیرکلاس‌سازی یا تغییر کد کلاس اولیه، نیاز به تغییر رفتار آن کلاس دارید. 18 | - اصلاح رفتار یک شیء باید داینامیک باشد. 19 | - نیاز به ارائهٔ قابلیتی هستید که بتواند ویژگی‌های مختلف مستقلی را به کلاس اضافه کند به طوری که هر ترکیب یا ترتیبی از این ویژگی‌ها قابل اعمال باشد. 20 | 21 | 22 | # اجزاء الگو 23 | - Component: تعریف اینترفیس و تعریف عملیات لازم. 24 | - ConcreteComponent: پیاده‌سازی اینترفیس و عملیات. 25 | - Decorator: این کلاس با کامپوننت، رابطهٔ اگریگیشن دارد و داخل خود، یک نمونه از کامپوننت را نگهداری می‌کند. 26 | - ConcreteDecoratorA 27 | 28 | # مثال ۱ 29 | فرض کنید که یک بستنی فروش سه نوع بستنی لیوانی، قیفی و چوبی دارد. این بستنی فروش هنگام فروش هر یک از این بستنی‌ها طبق سلیقهٔ مشتری، بستنی را با عسل، کاکائو، شکلات، بادام و ... `تزئین` می‌کند. 30 | 31 | # مثال‌های واقعی 32 |
33 | - All subclasses of java.io.InputStream, OutputStream, Reader and Writer have a constructor taking an instance of same type. 34 | - java.util.Collections, the checkedXXX(), synchronizedXXX() and unmodifiableXXX() methods. 35 | - javax.servlet.http.HttpServletRequestWrapper and HttpServletResponseWrapper 36 |
37 | 38 | # بیشتر بخوانید 39 |
40 | 1. http://javapapers.com/design-patterns/decorator-pattern/ یک مثال خوب و ساده با جاوا 41 | 42 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | بدون مشخص کردن کلاس‌های کانکرت، واسطی برای ساخت خانواده‌ای از اشیاء وابسته یا مرتبط با یکدیگر فراهم می‌کند. 4 | 5 | 6 | 7 | # نکات طراحی 8 | - وظیفهٔ این الگو، تعریفِ واسطی برای خانواده‌ای از محصولات است. 9 | - اگر چند نوع محصول و چند کارخانهٔ مختلف برای تولید این محصولات داشته باشیم از این الگو استفاده می‌کنیم. 10 | - وقتی که ساخت محصولات باید از سیستمی که از آن‌ها استفاده می‌کند مستقل باشد این الگو مفید است. 11 | 12 | # ساختار 13 | ![Abstract Factory UML](http://javaobsession.files.wordpress.com/2010/07/abstract-factory1.png) 14 | 15 | # مثال 16 | 17 | کارخانه‌ها به سه دسته تقسیم می‌شوند (نوکیا/سامسونگ/اچ‌تی‌سی) و محصولات به دو دستهٔ (گوشی‌های هوشمند/گوشی‌های غیرهوشمند) 18 | در این مثال ابتدا یک کلاس انتزاعی از کارخانه‌ها می‌سازیم که این کلاس دو متد دارد، یکی ساخت گوشی هوشمند آن کارخانه و دیگری ساخت گوشی غیرهوشمند آن کارخانه. 19 | 20 | سپس از کلاس انتزاعی کارخانه، سه کلاس نوکیا و سامسونگ و اچ‌تی‌سی می‌سازیم که هر کدام از این کارخانه‌ها دو نوع گوشی هوشمند و غیر هوشمند خود را می‌سازند. 21 | 22 | در این مثال، کلاینت ما از نام گوشی‌ها با خبر نیست. مثلاً نمی‌داند که گوشی هوشمند سامسونگ چیست. کلاینت درخواستش را اعلام می‌کند. مثلاً می‌گوید گوشی هوشمند سامسونگ را می‌خواهم. کلاس کانکرت کارخانهٔ سامسونگ درون کلاس ساخت گوشی هوشمند خود، گالاکسی‌اس۲ را می‌سازد. 23 | 24 | متن کامل مثال: http://www.codeproject.com/Articles/331304/Understanding-and-Implementing-Abstract-Factory-Pa 25 | 26 | # مثال‌های واقعی 27 |
28 | - javax.xml.parsers.DocumentBuilderFactory#newInstance() 29 | - javax.xml.transform.TransformerFactory#newInstance() 30 | - javax.xml.xpath.XPathFactory#newInstance() 31 | 32 | # بیشتر بخوانید 33 | 1. [Simple Factory vs. Factory Method vs. Abstract Factory](http://corey.quickshiftconsulting.com/1/post/2009/5/first-post.html) 34 | 2. [Wikipedia: Abstract factory pattern](http://en.wikipedia.org/wiki/Abstract_factory_pattern) 35 | 3. [Core J2EE Patterns - Data Access Object](http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) 36 | -------------------------------------------------------------------------------- /Structural/Flyweight/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | استفادهٔ دوبارهٔ بسیاری از اشیاء fine-grain را با اشتراک آن‌ها در سیستم، آسان می‌کند. 4 | 5 | # ساختار 6 | ![Flyweight UML](http://javaobsession.files.wordpress.com/2010/07/flyweight-pattern1.png) 7 | 8 | 9 | # اجزاء 10 | - Flyweight 11 | - ConcreteFlyweight 12 | - UnsharedConcreteFlyweight (اختیاری، می‌توان در طراحی از این کلاس استفاده نکرد.) 13 | - FlyweightFactory 14 | - Client 15 | 16 | # نکات طراحی 17 | - شیء flyweight، شیئ است که استفاده از حافظه را با اشتراک‌گذاری اشیاء مشابه، کاهش می‌دهد. این روشی‌ست برای استفاده از تعداد بسیار زیادی از اشیاء مشابه که نمی‌توان همهٔ آن‌ها را در حافظه ایجاد کرد و یا هزینهٔ زیادی در بر دارند. 18 | - هر شیء flyweight دو نوع ویژگی دارد، ویژگی ذاتی و درونی، ویژگی عارضی. 19 | 20 | وقتی از این الگو استفاده کنید که 21 | - اشیاء بسیار زیادی دارید که داده‌های مشابهی دارند و هزینهٔ حافظهٔ آن‌ها زیاد است. 22 | - اشیاء مشترک کم، می‌توانند جایگزین اشیاء به اشتراک گذاشته نشدهٔ زیاد شوند. 23 | - هویت هر شیء چندان مهم نیست. 24 | 25 | # مثال 26 | وقتی بخواهیم ویرایشگری طراحی کنیم که نویسه‌ها را در ویرایشگر نمایش دهد، اگر بخواهیم برای هر نویسه یک شیء در نظر بگیریم، سربار زیادی برای سیستم خواهد داشت. راه حل ساده این است که برای هر یک از حروف الفبا یک شیء flyweight در نظر می‌گیریم. سپس به صورت اشتراکی از آن‌ها استفاده می‌کنیم. 27 | 28 | # مثال‌های واقعی 29 |
30 | - java.lang.Integer#valueOf(int) (also on Boolean, Byte, Character, Short and Long) 31 | 32 |
33 | # اطلاعات بیشتر 34 |
35 | 1. [Flyweight Design Pattern; Java Papers](http://javapapers.com/design-patterns/flyweight-design-pattern/) 36 | 2. [C++ example of Flyweight Design Pattern](http://advancedcppwithexamples.blogspot.de/2010/10/c-example-of-flyweight-design-pattern.html) 37 | 3. [Source Making flyweight design pattern](http://sourcemaking.com/design_patterns/flyweight) 38 | 4. [Flyweight Design Pattern](http://dofactory.com/Patterns/PatternFlyweight.aspx) 39 | 5. [مثالی از بازی سودوکو پیاده‌شده توسط الگوی flyweight](http://cgeers.com/2008/03/08/flyweight-pattern/) 40 | -------------------------------------------------------------------------------- /Creational/AbstractFactory/AbstractFactory/C++/AbstractFactory.cpp: -------------------------------------------------------------------------------- 1 | //source: https://github.com/wxjeacen/DesignPattern.git 2 | 3 | #include 4 | #include "AbstractFactory.hpp" 5 | using namespace std; 6 | 7 | ConcreateProductA1::ConcreateProductA1() { 8 | cout << "Construction of ConreateProductA1" << endl; 9 | } 10 | 11 | ConcreateProductA1::~ConcreateProductA1() { 12 | cout << "Destruction of ConcreateProductA1" << endl; 13 | } 14 | 15 | ConcreateProductA2::ConcreateProductA2() { 16 | cout << "Construction of ConcreateProductA2" < 2 | # هدف 3 | واسط یکپارچه‌ای را برای مجموعه‌ای از واسط‌ها در زیر سیستم، ارائه می‌دهد. این الگو واسط سطح-بالاتری را تعریف می‌کند که استفاده از زیرسیستم را ساده‌تر می‌کند. 4 | 5 | # ساختار 6 | ![Facade UML](http://javaobsession.files.wordpress.com/2010/07/facade-pattern.png) 7 | 8 | # نکات طراحی 9 | الگوی طراحی Facade، اینترفیس را ساده‌تر می‌کند. 10 | 11 | زمانی از این الگو استفاده کنید که 12 | - نیاز به واسط ساده‌ای دارید که دسترسی به سیستم پیچیده را فراهم کند. 13 | - نیاز به کاهش کوپلینگ (اتصال‌ها) بین پیاده‌سازی‌های سیستم و کارخواه‌ها دارید. 14 | - نیاز به لایه‌بندی زیرسیستم‌ها دارید. 15 | 16 | # اجزاء الگو 17 | - Facade 18 | - Subsystem classes 19 | 20 | 21 | # Law of Demeter (LoD) or Principle of Least Knowledge 22 | تنها با دوستان بی‌واسطهٔ خود مذاکره کنید. این اصل یکی از روش‌های ایجاد Loose Coupling است. 23 | 24 | تنها متدهایی را صدا بزنید که متعلق به 25 | 1. شیء خودتان باشد. 26 | 2. آبجت‌هایی که توسط پارامتر به شیء شما منتقل شده‌اند. 27 | 3. هر شیء‌ای که خودتان تولید یا نمونه‌سازی می‌کنید. 28 | 4. کامپوننت‌های خودتان (HAS-A) 29 | 30 | هیچ کدام یک از راهنماهای بالا عنوان نمی‌کند که شما می‌توانید متدهای یک شیء که توسط متدهای دیگر برگردانده می‌شود را صدا بزنید، مثلاً کد زیر خلاف این اصل است: 31 |
32 | ```Java 33 | public float getTemp() { 34 | return station.getThermometer().getTemperature(); 35 | } 36 | ``` 37 |
38 | یا مثلاً کد معروف جاوا: 39 |
40 | ```Java 41 | System.out.println(); 42 | ``` 43 |
44 | # مثال‌های واقعی 45 |
46 | - javax.faces.context.FacesContext, it internally uses among others the abstract/interface types LifeCycle, ViewHandler, NavigationHandler and many more without that the enduser has to worry about it (which are however overrideable by injection). 47 | - javax.faces.context.ExternalContext, which internally uses ServletContext, HttpSession, HttpServletRequest, HttpServletResponse, etc. 48 |
49 | # اطلاعات بیشتر 50 |
51 | 1. http://zuta-developer.blogspot.com/2012/06/facade-pattern.html#.UVabkCEqgYQ 52 | -------------------------------------------------------------------------------- /Behavioural/Iterator/AnimalIterator/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.codeproject.com/Articles/362986/Understanding-and-Implementing-the-Iterator-Patter 3 | */ 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Iterator { 9 | public: 10 | virtual const char* next() = 0; 11 | virtual bool hasNext() = 0; 12 | }; 13 | 14 | class Aggregate { 15 | public: 16 | virtual Iterator* getIterator() = 0; 17 | virtual const char* getItem( int ) = 0; 18 | virtual int size() = 0; 19 | }; 20 | 21 | class AnimalIterator : public Iterator { 22 | public: 23 | AnimalIterator( Aggregate* aggregate ) 24 | : _current( 0 ), 25 | _aggregate( aggregate ) 26 | { 27 | } 28 | 29 | const char* next() { 30 | const char* item = _aggregate->getItem( _current ); 31 | _current++; 32 | return item; 33 | } 34 | 35 | bool hasNext() { 36 | if (_current >= _aggregate->size() || _aggregate->getItem(_current) == NULL) 37 | return false; 38 | else 39 | return true; 40 | 41 | 42 | // (_aggregate->size() != _current); 43 | } 44 | 45 | private: 46 | Aggregate* _aggregate; 47 | int _current; 48 | }; 49 | 50 | class AnimalAggregate : public Aggregate { 51 | public: 52 | AnimalAggregate() { 53 | } 54 | 55 | void addAnimal( const char* value ) { 56 | _animals.push_back( value ); 57 | } 58 | 59 | Iterator* getIterator() { 60 | Iterator* iter = new AnimalIterator( this ); 61 | return iter; 62 | } 63 | 64 | const char* getItem( int index ) { 65 | return _animals[index]; 66 | } 67 | 68 | int size() { 69 | return _animals.size(); 70 | } 71 | 72 | private: 73 | vector _animals; 74 | }; 75 | 76 | 77 | int main() { 78 | 79 | AnimalAggregate* aggregate = new AnimalAggregate(); 80 | aggregate->addAnimal("Cat"); 81 | aggregate->addAnimal("Fish"); 82 | aggregate->addAnimal("Duck"); 83 | aggregate->addAnimal("Snake"); 84 | aggregate->addAnimal("Ant"); 85 | 86 | Iterator* iter = aggregate->getIterator(); 87 | 88 | while( iter->hasNext() ) { 89 | cout << iter->next() << endl; 90 | } 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /Structural/Composite/Classic/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class Component { 7 | public: 8 | virtual void operation() = 0; 9 | 10 | virtual void add( Component* child ) { } 11 | virtual void remove( Component* child ) { } 12 | virtual Component* getChild( int index ) { return NULL; } 13 | }; 14 | 15 | class Leaf : public Component { 16 | public: 17 | virtual void operation() { 18 | cout << "Operation by leaf" << endl; 19 | } 20 | }; 21 | 22 | class Composite : public Component { 23 | public: 24 | 25 | virtual void add( Component* child ) { 26 | _components.push_back( child ); 27 | } 28 | 29 | virtual void remove( Component* child ) { 30 | list::iterator iter; 31 | iter = find( _components.begin(), _components.end(), child); 32 | 33 | if ( _components.end() != iter ) { 34 | _components.erase( iter ); 35 | } 36 | } 37 | 38 | virtual Component* getChild( int index ) { 39 | list::iterator iter1, iter2; 40 | int i; 41 | for ( i = 1, iter1 = _components.begin(), iter2 = _components.end(); 42 | iter1 != iter2; 43 | ++iter1, ++i) { 44 | if ( i == index ) 45 | break; 46 | } 47 | 48 | return *iter1; 49 | } 50 | 51 | virtual void operation() { 52 | cout << "Operation by Composite" << endl; 53 | list::iterator iter1, iter2; 54 | 55 | for( iter1 = _components.begin(), iter2 = _components.end(); 56 | iter1 != iter2; 57 | ++iter1) { 58 | (*iter1)->operation(); 59 | } 60 | } 61 | 62 | private: 63 | list _components; 64 | }; 65 | 66 | int main() { 67 | Leaf* leaf1 = new Leaf(); 68 | Leaf* leaf2 = new Leaf(); 69 | 70 | Composite* composite = new Composite(); 71 | composite->add( leaf1 ); 72 | composite->add( leaf2 ); 73 | Composite* composite2 = new Composite(); 74 | composite2->add( new Leaf() ); 75 | composite2->add( new Leaf() ); 76 | composite2->add( new Leaf() ); 77 | composite2->add( new Leaf() ); 78 | composite->add( composite2 ); 79 | 80 | composite->operation(); 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /Behavioural/ChainOfResponsibility/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | با دادن بیشتر از یک شیء برای هندل کردن درخواست از جفتگری (کوپلینگ) فرستندهٔ درخواست و گیرندهٔ درخواست اجتناب می‌کند. اشیاء گیرنده را زنجیر می‌کند و درخواست را در امتداد زنجیر گذر می‌دهد تا زمانی که یکی از اشیاء آن را هندل کند. 4 | 5 | # ساختار 6 | ## Class Diagram 7 | ![class diagram](http://javaobsession.files.wordpress.com/2010/07/chain-of-responsibility-pattern.png) 8 | 9 | ## Sequence diagram 10 | ![sequence diagram](http://javaobsession.files.wordpress.com/2010/07/chain-of-responsibility-pattern-sd.png) 11 | 12 | # اجزاء الگو 13 | - Handler 14 | - ConcreteHandler 15 | - Client 16 | 17 | # نکات طراحی 18 | از این الگو زمانی استفاده کنید که 19 | - لازم است درخواست‌ها توسط چندین شیء که در زمانِ اجرا مشخص می‌شوند، هندل شوند. 20 | - درخواست‌ها باید به روش «پاسخ بده یا واگذار کن» مدیریت شوند. 21 | 22 | # مثال ۱ 23 | فرض کنید می‌خواهیم پرونده‌ای که رمزنگاری شده است را رمزگشایی کنیم. ما ۱۰ الگوریتم متفاوت برای رمزگشایی این پرونده طراحی کرده‌ایم. مسلماً بهترین راه این است که از الگوریتم‌های فراگیر، آسان و آن‌هایی که احتمال می‌دهیم زودتر پرونده‌مان را رمزنگاری می‌کنند شروع کنیم. بنابراین طبق سیاست‌هایی که داریم این ۱۰ الگوریتم را مرتب می‌کنیم. حال توسط `الگوی طراحی زنجیرهٔ پاسخگویی` این ۱۰ الگوریتم را به این پرونده اعمال می‌کنیم تا بالاخره یکی از این الگوریتم‌ها بتوانند پرونده‌مان را رمزگشایی کنند. توجه این که ممکن است هیچ کدام از این الگوریتم‌ها نتوانند پرونده را رمزگشایی کنند. 24 | 25 | # مثال ۲ 26 | یک مثال معروف از الگوی طراحی زنجیرهٔ پاسخگویی، مبحث مدیریت استناء‌ها در زبان‌های برنامه‌نویسی شیء‌گرا مثل C++ و جاوا است. 27 | 28 | # مثال‌های واقعی 29 |
30 | - java.util.logging.Logger#log() 31 | - javax.servlet.Filter#doFilter() 32 | 33 |
34 | 35 | # اطلاعات بیشتر 36 | 1. [پویش پرونده با فرمت‌های متفاوت](http://blog.sanaulla.info/2012/09/23/simple-example-to-illustrate-chain-of-responsibility-design-pattern/) 37 | 2. [مدیریت رایانامه‌های متفاوت](http://java.dzone.com/articles/design-patterns-uncovered-chain-of-responsibility) 38 | 3. [دو مثال خوب دیگر، شناسایی انوع پول و سکه و شناسایی اعداد](http://javapapers.com/design-patterns/chain-of-responsibility-design-pattern/) 39 | 40 | -------------------------------------------------------------------------------- /Behavioural/State/SunState/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Sun; 5 | 6 | class State { 7 | public: 8 | virtual void nextState( Sun* sun ) = 0; 9 | virtual const char* toString() = 0; 10 | }; 11 | 12 | class Bamdad : public State { 13 | public: 14 | virtual void nextState( Sun* sun ); 15 | virtual const char* toString() { 16 | return "Bamdad"; 17 | } 18 | }; 19 | 20 | class Chasht : public State { 21 | public: 22 | virtual void nextState( Sun* sun ); 23 | virtual const char* toString() { 24 | return "Chasht"; 25 | } 26 | }; 27 | 28 | class Shamgah : public State { 29 | public: 30 | virtual void nextState( Sun* sun ); 31 | virtual const char* toString() { 32 | return "Shamgah"; 33 | } 34 | }; 35 | 36 | class Shabangah : public State { 37 | public: 38 | virtual void nextState( Sun* sun ); 39 | virtual const char* toString() { 40 | return "Shabangah"; 41 | } 42 | }; 43 | 44 | class Sun { 45 | public: 46 | Sun( State* state ) 47 | :_state( state ) { 48 | } 49 | 50 | void afterSixHours() { 51 | _state->nextState( this ); 52 | } 53 | 54 | void changeState( State* state ) { 55 | _state = state; 56 | } 57 | 58 | const char* getState() { 59 | return _state->toString(); 60 | } 61 | 62 | private: 63 | State* _state; 64 | }; 65 | 66 | void Bamdad::nextState( Sun* sun ) { 67 | sun->changeState( new Chasht() ); 68 | } 69 | 70 | void Chasht::nextState( Sun* sun ) { 71 | sun->changeState( new Shamgah() ); 72 | } 73 | 74 | void Shamgah::nextState( Sun* sun ) { 75 | sun->changeState( new Shabangah() ); 76 | } 77 | 78 | void Shabangah::nextState( Sun* sun ) { 79 | sun->changeState( new Bamdad() ); 80 | } 81 | 82 | int main() { 83 | 84 | Sun* sun = new Sun( new Bamdad() ); 85 | sun->afterSixHours(); 86 | cout << sun->getState() << endl; 87 | 88 | sun->afterSixHours(); 89 | cout << sun->getState() << endl; 90 | 91 | sun->afterSixHours(); 92 | cout << sun->getState() << endl; 93 | 94 | sun->afterSixHours(); 95 | cout << sun->getState() << endl; 96 | 97 | sun->afterSixHours(); 98 | cout << sun->getState() << endl; 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /Behavioural/Iterator/Classic/C++/1/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | typedef int DATA; 5 | class Iterator; 6 | 7 | class Aggregate { 8 | public: 9 | virtual Iterator* createIterator(Aggregate* aggregate) = 0; 10 | virtual int getSize() = 0; 11 | virtual DATA getItem(int nIndex) = 0; 12 | }; 13 | 14 | class Iterator { 15 | public: 16 | virtual void first() = 0; 17 | virtual void next() = 0; 18 | virtual bool isDone() = 0; 19 | virtual DATA currentItem() = 0; 20 | }; 21 | 22 | class ConcreteIterator : public Iterator { 23 | public: 24 | ConcreteIterator( Aggregate* aggregate ) 25 | :_concreteAggregate( aggregate ), 26 | _index( 0 ) 27 | { 28 | 29 | } 30 | 31 | virtual void first() { 32 | _index = 0; 33 | } 34 | 35 | virtual void next() { 36 | if ( _index < _concreteAggregate->getSize() ) { 37 | ++_index; 38 | } 39 | } 40 | 41 | virtual bool isDone() { 42 | return (_index == _concreteAggregate->getSize()); 43 | } 44 | 45 | virtual DATA currentItem() { 46 | return _concreteAggregate->getItem(_index); 47 | } 48 | private: 49 | Aggregate* _concreteAggregate; 50 | int _index; 51 | }; 52 | 53 | 54 | 55 | class ConcreteAggregate : public Aggregate { 56 | public: 57 | ConcreteAggregate( int size ) 58 | :_size( size ), 59 | _data( NULL ) 60 | { 61 | _data = new DATA[_size]; 62 | 63 | for ( int i = 0; i < size; ++i ) { 64 | _data[i] = i; 65 | } 66 | } 67 | 68 | virtual Iterator* createIterator( Aggregate* aggregate) { 69 | return new ConcreteIterator( this ); 70 | } 71 | 72 | virtual int getSize() { 73 | return _size; 74 | } 75 | 76 | virtual DATA getItem( int index ) { 77 | if ( index < _size ) { 78 | return _data[index]; 79 | } else { 80 | return -1; 81 | } 82 | } 83 | 84 | private: 85 | int _size; 86 | DATA* _data; 87 | }; 88 | 89 | int main() { 90 | 91 | Aggregate* aggregate = new ConcreteAggregate( 4 ); 92 | Iterator* iterator = new ConcreteIterator( aggregate ); 93 | 94 | for (; false == iterator->isDone(); iterator->next() ) { 95 | cout << iterator->currentItem() << endl; 96 | } 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /Behavioural/README.md: -------------------------------------------------------------------------------- 1 | # Behavioural Patterns 2 | 3 |
4 | - [Chain Of Responsibility](ChainOfResponsibility): با دادن بیشتر از یک شیء برای هندل کردن درخواست از جفتگری (کوپلینگ) فرستندهٔ درخواست و گیرندهٔ درخواست اجتناب می‌کند. اشیاء گیرنده را زنجیر می‌کند و درخواست را در امتداد زنجیر گذر می‌دهد تا زمانی که یکی از اشیاء آن را هندل کند. 5 | 6 | - [Command](Command): درخواست را به عنوان یک شیء کپسوله می‌کند، از این رو اجازه می‌دهد تا بتوانید کارخوه‌ها را با درخواست‌ها، صف‌ها و یا لاگ‌های متفاوت پارامتری کنید. 7 | 8 | - [Interpreter](Interpreter): یک بازنمایی برای گرامر زبان داده شده تعریف می‌کند و مفسر توسط این باز نمایی، جملات زبان را تفسیر می کند. 9 | 10 | - [Iterator](Iterator): روشی برای دستری به عناصر یک شیء اگریگیت فراهم می‌کند بدون اینکه اصول پیاده‌سازی و ساختمان دادهٔ لایهٔ زیرین اگریگیت را نمایش دهد. 11 | 12 | - [Mediator](Mediator): شیء‌ای را تعریف می‌کند که نحوهٔ ارتباط بین مجوعه‌ای از اشیاء را کپسوله می‌کند. این الگو با جلوگیری ارتباط صریح بین اشیاء از جفتگری ضعیف (loose coupling) پشتیبانی می‌کند. 13 | 14 | - [Memento](Memento): بدون تخلف از کپسوله‌سازی، وضعیت داخلی شیء ضبط و استخراج می‌کند از این رو شیء بعداً می‌تواند به این حالت برگردد. 15 | 16 | - [Observer](Observer): وابستگی یک-به-چند بین اشیاء تعریف می‌کند بنابراین وقتی یک شیء وضعیت‌اش را تغییر می‌دهد، تمامی اشیاء وابسته به آن از آن تغییر مطلع شده و به صورت خودکار به روز می‌شوند. 17 | 18 | - [State](State): به شیء این اجازه را می‌دهد که وقتی وضعیت درونی‌اش تغییر کرد، رفتارش را تغییر دهد. به نظر می‌رسد که شیء کلاس خود را عوض می‌کند. 19 | 20 | - [Strategy](Strategy): خانواده‌ای از الگوریتم ها را تعریف می‌کند، هر یک را کپسوله می‌کند و آن‌ها را جابه‌جا پذیر می‌کند. الگوی استراتژی اجازه می‌دهد که الگوریتم‌ها مستقل از کارخواهی که از آن‌ها استفاده می‌کند، تغییر کنند. 21 | 22 | - [Template Method](TemplateMethod): استخوان‌بندی و شالودهٔ اصلی عملیات الگوریتم را تعریف می‌کند، و پیاده‌سازی هر مرحله را به زیرکلاس‌ها می‌سپارد. این الگو، به زیرکلاس‌ها این اختیار را می‌دهد که تا خودشان، مراحل الگوریتم را پیاده کنند بدون اینکه ساختار الگوریتم را تغییر دهند. 23 | 24 | - [Visitor](Visitor): اعمالی که باید روی عناصری از شیء اجرا شود را ارائه می‌کند. این الگو اجازه را می‌دهد تا اعمال جدیدی تعریف کنید بدون اینکه کلاس‌هایی که این اعمال روی آن‌ها انجام می‌شود را تغییر دهید. 25 | 26 | 27 | -------------------------------------------------------------------------------- /Creational/Singleton/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # هدف 4 | 1. تضمین می‌کند که کلاس تنها یک نمونه داشته باشد و دسترسی سراسری برای آن فراهم می‌کند. 5 | 6 | 7 | # موارد استفاده 8 | 1. هر گاه بخواهیم مطمئن شویم که فقط یک نمونه از کلاس می‌تواند وجود داشته باشد، و دسترسی سراسری به آن داشته باشیم، از این الگو استفاده می‌کنیم. (زمانی که تنها یک نمونه از کلاس لازم یا نیاز است) 9 | 2. زمانی که کنترل دسترسی به تنها یک شیء لازم است. 10 | 11 | # ساختار 12 | ![UML](http://javaobsession.files.wordpress.com/2010/06/56b5c960.png) 13 | 14 | # پیاده‌سازی 15 | 1. کانستراکتور کلاس را پرایویت می‌کنیم تا کسی نتواند آن کلاس را خارج از کلاس new کند. 16 | 2. داخل کلاس یک متود استاتیک تعریف می‌کنیم و تنها یک نمونه از کلاس تولید می‌کنیم. اگر قبلاً یک نمونه تولید شده بود، همان نمونهٔ قبلی را برمی‌گردانیم. 17 | 18 | # Singleton and lazy instantiation 19 | می‌توانیم نمونه‌سازی کلاس سینگلتون را تا زمان اولین دسترسی به تأخیر بیاندازیم. اطلاعات بیشتر: [lazy initialization](http://en.wikipedia.org/wiki/Lazy_initialization) 20 | 21 | # Multithreading and Singleton 22 | 1. [Singleton in multi-threaded environment](http://taskinoor.wordpress.com/2011/04/18/singleton_multithreaded/) 23 | 2. باید این الگو را طوری به کار ببریم که thread safe باشد. 24 | 25 | # Double-checked locking 26 | در محیط‌های چند نخی، گرفتن و آزاد کردن lock خیلی هزینه‌بر است و ممکن است تعداد این درخواست‌ها خیلی خیلی زیاد شود. برای کاهش سربار lock می‌توان پس از اینکه فلگ را چک کردیم lock کنیم تا سربار کاهش یابد. 27 | 1. [Double-checked locking](http://en.wikipedia.org/wiki/Double-checked_locking) 28 | 2. [Double-checked locking and the Singleton pattern](http://www.ibm.com/developerworks/java/library/j-dcl/index.html) 29 | 3. [The "Double-Checked Locking is Broken" Declaration](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) 30 | 31 | # جنبه‌های منفی 32 | 1. تا زمانی که سازندهٔ کلاس سینگلتون خصوصی‌ست، اشتقاق و زیرکلاس‌سازی امکان ناپذیر است. 33 | 34 | # مثال‌های واقعی 35 |
36 | - java.lang.Runtime#getRuntime() 37 | - java.awt.Desktop#getDesktop() 38 | 39 | # بیشتر بخوانید 40 | 1. http://stackoverflow.com/questions/86582/singleton-how-should-it-be-used 41 | 2. http://www.yolinux.com/TUTORIALS/C++Singleton.html 42 | 3. http://stackoverflow.com/questions/1008019/c-singleton-design-pattern 43 | -------------------------------------------------------------------------------- /Behavioural/Mediator/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Colleague; 6 | 7 | class Mediator { 8 | public: 9 | virtual void send( const char* message, Colleague* colleague ) = 0; 10 | }; 11 | 12 | 13 | class Colleague { 14 | public: 15 | Colleague( Mediator* mediator ) 16 | :_mediator( mediator ) { 17 | } 18 | 19 | virtual void notify( const char* message ) = 0; 20 | 21 | protected: 22 | Mediator* _mediator; 23 | }; 24 | 25 | class ConcreteColleague1 : public Colleague { 26 | public: 27 | ConcreteColleague1( Mediator* mediator ) 28 | :Colleague( mediator ) { 29 | } 30 | 31 | void send( const char* message ) { 32 | _mediator->send( message, this ); 33 | } 34 | 35 | void notify( const char* message ) { 36 | cout << "ConcreteColleague1 gets message: " << message << endl; 37 | } 38 | }; 39 | 40 | 41 | class ConcreteColleague2 : public Colleague { 42 | public: 43 | ConcreteColleague2( Mediator* mediator ) 44 | :Colleague( mediator ) { 45 | } 46 | 47 | void send( const char* message ) { 48 | _mediator->send( message, this ); 49 | } 50 | 51 | void notify( const char* message ) { 52 | cout << "ConcreteColleague2 gets message: " << message << endl; 53 | } 54 | }; 55 | 56 | class ConcreteMediator : public Mediator { 57 | public: 58 | void registerColleague( Colleague* colleague ) { 59 | _coleagues.push_back( colleague ); 60 | } 61 | 62 | virtual void send( const char* message, Colleague* colleague ) { 63 | for( vector::iterator it = _coleagues.begin(); 64 | it != _coleagues.end(); ++it ) { 65 | if ( *it != colleague ) { 66 | (*it)->notify( message ); 67 | } 68 | } 69 | } 70 | 71 | private: 72 | vector _coleagues; 73 | }; 74 | 75 | 76 | int main() { 77 | 78 | ConcreteMediator* mediator = new ConcreteMediator(); 79 | 80 | ConcreteColleague1* colleague1 = new ConcreteColleague1( mediator ); 81 | 82 | ConcreteColleague2* colleague2 = new ConcreteColleague2( mediator ); 83 | ConcreteColleague2* colleague3 = new ConcreteColleague2( mediator ); 84 | 85 | mediator->registerColleague( colleague1 ); 86 | mediator->registerColleague( colleague2 ); 87 | mediator->registerColleague( colleague3 ); 88 | mediator->registerColleague( colleague3 ); 89 | 90 | 91 | colleague1->send( "How are you?" ); 92 | colleague2->send( "Fine, thanks." ); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /Behavioural/Visitor/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | اعمالی که باید روی عناصری از شیء اجرا شود را ارائه می‌کند. این الگو اجازه را می‌دهد تا اعمال جدیدی تعریف کنید بدون اینکه کلاس‌هایی که این اعمال روی آن‌ها انجام می‌شود را تغییر دهید. 4 | 5 | # ساختار 6 | ![Visitor Pattern](http://javaobsession.files.wordpress.com/2010/07/visitor-pattern1.png) 7 | 8 | # نکات طراحی 9 | 10 | # مثال 11 | فرض کنید سلسله مراتبی از ساختار حیوانات به صورت زیر داشته باشیم: 12 |
13 | ```c++ 14 | class Animal { }; 15 | class Dog : public Animal { }; 16 | class Cat : public Animal { }; 17 | ``` 18 |
19 | فرض کنید بخواهیم که عملیات جدیدی برای این سلسله مراتب تعیین کنیم تا هر حیوان صدای مخصوص به خود را ایجاد کند. با استفاده از پلی‌مورفیزم این کار را انجام می‌دهیم. 20 |
21 | ```c++ 22 | class Animal { 23 | public: virtual void makeSound() = 0; 24 | }; 25 | 26 | class Dog : public Animal { 27 | public: viod makeSound { cout << "woof!" << endl } 28 | }; 29 | 30 | class Cat : public Animal { 31 | public: void makeSound { cout << "meow!" << endl; } 32 | }; 33 | ``` 34 |
35 | با این روش هر بار که بخواهیم رفتار جدیدی به این ساختار سلسله مراتبی اضافه کنیم مجبوریم هر یک از کلاس‌ها را تک تک تغییر دهیم. به کمک الگوی ویزیتور می‌توانیم از این ضعف طراحی جلوگیری کنیم: 36 |
37 | ```c++ 38 | class Operation; 39 | 40 | class Animal { 41 | public: 42 | virtual void letsDo( Operation* op ) = 0; 43 | }; 44 | 45 | class Cat; 46 | class Dog; 47 | 48 | class Operation { 49 | public: 50 | virtual void catOperation( Cat* cat ) = 0; 51 | virtual void dogOperation( Dog* dog ) = 0; 52 | }; 53 | 54 | class Sound : public Operation { 55 | public: 56 | void dogOperation(Dog* dog ) { 57 | cout << "woof!" << endl; 58 | } 59 | 60 | void catOperation(Cat* cat ) { 61 | cout << "meow!" << endl; 62 | } 63 | }; 64 | 65 | class Dog : public Animal { 66 | public: 67 | void letsDo( Operation* op ) { 68 | op->dogOperation( this ); 69 | } 70 | }; 71 | 72 | class Cat : public Animal { 73 | public: 74 | void letsDo( Operation* op ) { 75 | op->catOperation( this ); 76 | } 77 | }; 78 | 79 | int main() { 80 | 81 | Cat* cat = new Cat(); 82 | Sound* sound = new Sound(); 83 | cat->letsDo( sound ); 84 | 85 | return 0; 86 | } 87 | ``` 88 |
89 | مثال از اینجا: http://stackoverflow.com/a/255300/225052 90 | 91 | # مثال‌های واقعی 92 |
93 | - javax.lang.model.element.AnnotationValue and AnnotationValueVisitor 94 | - javax.lang.model.element.Element and ElementVisitor 95 | - javax.lang.model.type.TypeMirror and TypeVisitor 96 | -------------------------------------------------------------------------------- /Behavioural/Command/DeviceController/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Command { 5 | public: 6 | virtual void execute() = 0; 7 | }; 8 | 9 | //Receiver 10 | class Receiver { 11 | public: 12 | virtual void switchOn() = 0; 13 | virtual void switchOff() = 0; 14 | }; 15 | 16 | class Light : public Receiver { 17 | public: 18 | void switchOn() { 19 | _on = true; 20 | cout << "Light is switched on" << endl; 21 | } 22 | 23 | void switchOff() { 24 | _on = false; 25 | cout << "Light is switched off" << endl; 26 | } 27 | private: 28 | bool _on; 29 | }; 30 | 31 | class Television : public Receiver { 32 | public: 33 | void switchOn() { 34 | _on = true; 35 | cout << "Television is switched on" << endl; 36 | } 37 | 38 | void switchOff() { 39 | _on = false; 40 | cout << "Television is switched off" << endl; 41 | } 42 | 43 | private: 44 | bool _on; 45 | }; 46 | 47 | //ConcreteCommand1 48 | class OnCommand : public Command { 49 | public: 50 | OnCommand(Receiver* receiver) 51 | :_receiver(receiver) { 52 | } 53 | 54 | void execute() { 55 | _receiver->switchOn(); 56 | } 57 | 58 | private: 59 | Receiver* _receiver; 60 | }; 61 | 62 | 63 | //ConcreteCommand2 64 | class OffCommand : public Command { 65 | public: 66 | OffCommand(Receiver* receiver) 67 | :_receiver(receiver) { 68 | } 69 | 70 | void execute() { 71 | _receiver->switchOff(); 72 | } 73 | private: 74 | Receiver* _receiver; 75 | }; 76 | 77 | //Invoker 78 | class RemoteControl { 79 | public: 80 | void setCommand(Command* command) { 81 | _command = command; 82 | } 83 | void pressButton() { 84 | _command->execute(); 85 | } 86 | 87 | private: 88 | Command* _command; 89 | }; 90 | 91 | 92 | 93 | 94 | int main() { 95 | RemoteControl* control = new RemoteControl(); 96 | 97 | Receiver* light = new Light(); 98 | 99 | Command* lightsOn = new OnCommand( light ); 100 | Command* lightsOff = new OffCommand( light ); 101 | 102 | //switch on light 103 | control->setCommand( lightsOn ); 104 | control->pressButton(); 105 | 106 | //switch off light 107 | control->setCommand( lightsOff ); 108 | control->pressButton(); 109 | 110 | Receiver* tv = new Television(); 111 | 112 | Command* tvOn = new OnCommand( tv ); 113 | Command* tvOff = new OffCommand( tv ); 114 | 115 | //switch on TV 116 | control->setCommand( tvOn ); 117 | control->pressButton(); 118 | 119 | //switch off TV 120 | control->setCommand( tvOff ); 121 | control->pressButton(); 122 | 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /Behavioural/Observer/Classic/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://www.cppblog.com/converse/archive/2006/08/05/10858.html 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | typedef int STATE; 11 | 12 | class Observer; 13 | 14 | // Subject Interface (Observable) 15 | class Subject { 16 | public: 17 | Subject() 18 | :_subjectState( -1 ) { 19 | } 20 | 21 | void notify(); 22 | 23 | void attach( Observer* observer ) { 24 | cout << "attach an Observer" << endl; 25 | _listObserver.push_back( observer ); 26 | } 27 | 28 | void detach( Observer* observer ) { 29 | list::iterator iter; 30 | iter = find( _listObserver.begin(), _listObserver.end(), observer ); 31 | 32 | if ( _listObserver.end() != iter ) { 33 | _listObserver.erase( iter ); 34 | } 35 | cout << "detach and Observer" << endl; 36 | } 37 | 38 | virtual void setState( STATE state ) { 39 | cout << "setState by subject" << endl; 40 | _subjectState = state; 41 | } 42 | 43 | virtual STATE getState() { 44 | cout << "getState by subject" << endl; 45 | return _subjectState; 46 | } 47 | 48 | protected: 49 | STATE _subjectState; 50 | list _listObserver; 51 | }; 52 | 53 | 54 | 55 | class Observer { 56 | public: 57 | virtual void update( Subject* subject ) = 0; 58 | protected: 59 | STATE _observerState; 60 | }; 61 | 62 | class ConcreteSubject : public Subject { 63 | public: 64 | virtual void setState( STATE state ) { 65 | cout << "setState by ConcreteSubject" << endl; 66 | _subjectState = state; 67 | } 68 | 69 | virtual STATE getState() { 70 | cout << "getState by ConcreteSubject" << endl; 71 | return _subjectState; 72 | } 73 | }; 74 | 75 | class ConcreteObserver : public Observer { 76 | public: 77 | virtual void update( Subject* subject ) { 78 | if ( NULL == subject ) 79 | return; 80 | _observerState = subject->getState(); 81 | cout << "the ObserverState is " << _observerState << endl; 82 | } 83 | }; 84 | 85 | void Subject::notify() { 86 | cout << "notify observer's state" << endl; 87 | 88 | list::iterator iter1, iter2; 89 | for ( iter1 = _listObserver.begin(), iter2 = _listObserver.end(); 90 | iter1 != iter2; 91 | ++iter1 ) { 92 | (*iter1)->update( this ); 93 | } 94 | } 95 | 96 | int main() { 97 | 98 | Observer* observer1 = new ConcreteObserver(); 99 | Observer* observer2 = new ConcreteObserver(); 100 | 101 | Subject* subject = new ConcreteSubject(); 102 | 103 | subject->attach( observer1 ); 104 | subject->attach( observer2 ); 105 | 106 | subject->setState( 4 ); 107 | subject->notify(); 108 | 109 | subject->detach( observer1 ); 110 | subject->setState( 10 ); 111 | subject->notify(); 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /Structural/Flyweight/Characters/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://advancedcppwithexamples.blogspot.de/2010/10/c-example-of-flyweight-design-pattern.html 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Character { 11 | public: 12 | Character( const char ch, int width, int height, int ascent, int descent, int pointSize ) 13 | :_symbol( ch ), 14 | _width( width ), 15 | _height( height ), 16 | _ascent( ascent ), 17 | _descent( descent ), 18 | _pointSize( pointSize ) { 19 | } 20 | 21 | virtual void display( int pointSize ) = 0; 22 | protected: 23 | char _symbol; 24 | int _width; 25 | int _height; 26 | int _ascent; 27 | int _descent; 28 | int _pointSize; 29 | }; 30 | 31 | class CharacterA : public Character { 32 | public: 33 | CharacterA() 34 | :Character( 'A', 120, 100, 70, 0, 0) { 35 | } 36 | 37 | void display( int pointSize ) { 38 | _pointSize = pointSize; 39 | cout << _symbol << " (pointSize " << _pointSize << " )" << endl; 40 | } 41 | }; 42 | 43 | class CharacterB : public Character { 44 | public: 45 | CharacterB() 46 | :Character( 'B', 140, 100, 72, 0, 0 ) { 47 | } 48 | 49 | void display( int pointSize ) { 50 | _pointSize = pointSize; 51 | cout << _symbol << " (pointSize " << _pointSize << " )" << endl; 52 | } 53 | }; 54 | 55 | class CharacterZ : public Character { 56 | public: 57 | CharacterZ() 58 | :Character( 'Z', 100, 100, 68, 0, 0 ) { 59 | } 60 | 61 | void display( int pointSize ) { 62 | _pointSize = pointSize; 63 | cout << _symbol << " (pointSize " << _pointSize << " )" << endl; 64 | } 65 | }; 66 | 67 | class CharacterFctory { 68 | public: 69 | Character* geCharacter( char key ) { 70 | Character* character = NULL; 71 | if ( _characters.find( key ) != _characters.end() ) { 72 | character = _characters[key]; 73 | } else { 74 | switch ( key ) { 75 | case 'A': 76 | character = new CharacterA(); 77 | break; 78 | case 'B': 79 | character = new CharacterB(); 80 | break; 81 | case 'Z': 82 | character = new CharacterZ(); 83 | break; 84 | default: 85 | cout << "Not Implemented Yet" << endl; 86 | throw ( "Not Implemented" ); 87 | } 88 | _characters[ key ] = character; 89 | } 90 | return character; 91 | } 92 | 93 | private: 94 | map< char, Character* > _characters; 95 | }; 96 | 97 | int main() { 98 | 99 | string document = "AAZZBBZB"; 100 | const char* chars = document.c_str(); 101 | 102 | CharacterFctory* factory = new CharacterFctory(); 103 | 104 | int pointSize = 10; 105 | 106 | for ( size_t i = 0; i < document.length(); i++ ) { 107 | pointSize++; 108 | Character* character = factory->geCharacter( chars[ i ] ); 109 | character->display( pointSize ); 110 | } 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /Creational/FactoryMethod/Readme.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | واسطی برای ساخت اشیاء ایجاد می‌کند، اما به زیرکلاس‌ها اجازه می‌دهد که تصمیم بگیرند که چه کلاسی را نمونه‌سازی کنند. این الگو اجازه می‌دهد تا نمونه‌برداری کلاس، به زیرکلاس‌ها معوق شود. 4 | 5 | # نام دیگر 6 | Virtual Constructor 7 | 8 | # نکات طراحی 9 | - وابستگی به زیرکلاس را برای ساخت اشیاء از بین می‌برد. 10 | - برای زیرکلاس‌ها hook ارائه می‌کند. 11 | 12 | - Connects parallel class hierarchies. 13 | - در الگوی طراحی Factory Method از Simple Factory استفاده می‌کنیم. 14 | - در Simple Factory تنها یک کارخانه داریم. اما اگر چند کارخانه داشته باشیم که همگی این کارخانه‌ها محصولات مشابهی تولید کنند مثلاً همگی موبایل تولید می‌کنند (اما هر کارخانه پیاده‌سازی خودش را دارد) در چنین حالتی از Factory Method استفاده می‌کنیم. به این صورت یک رابط برای کارخانه‌ها ایجاد می‌کنیم و پیاده‌سازی متود ساخت محصول را به کارخانه‌ها واگذار می‌کنیم. هر یک از کارخانه‌ها از Simple Factory برای تولید محصولاتش استفاده می‌کند. 15 | - به روش بالا می گوییم: Allowing the subclasses to decide یا Real-time decision 16 | - برای اینکه پارامترهای Concrete Factory بتوانند `Type-Safe` باشند، می‌توانیم از `enum` استفاده کنیم و یا روش‌های بهتر. 17 | - وقتی که نمونه‌سازی اشیاء را در یک آبجکت یا متد، کپسوله کنیم، باعث بالا رفتن maintenance می‌شود و باعث می‌شود از کدهای اضافی و مجدد خودداری شود. 18 | - در این الگو اصل Dependency Inversion Principle رعایت می‌شود. 19 | 20 | # ساختار 21 | ![Factory Method Pattern UML](http://javaobsession.files.wordpress.com/2010/07/factory-method.png) 22 | 23 | # مثال 24 | ساخت موبایل از دو کارخانهٔ متفاوت 25 | 26 | ## Product (Mobile) 27 | یک واسط برای تمامی موبایل‌ها تعریف می‌کنیم و ویژگی‌ها و رفتارهای مشترک را ذکر می‌کنیم. 28 | 29 | 1. نام موبایل 30 | 2. رنگ 31 | 32 | ## ConcreateProduct 33 | واسط موبایل را برای موبایل‌های مختلف پیاده‌سازی می‌کنیم. 34 | 35 | 1. Nokia N900 36 | 2. Nokia N95 37 | 3. Motorola Atrix 38 | 4. Motorola A1200 39 | 40 | ## Creator/Factory 41 | واسط کارخانه 42 | createMobile() 43 | 44 | ## ConcreteCreator/ConcreteFactry 45 | هر کدام از کارخانه‌ها باید واسط کارخانه را پیاده‌سازی کنند. 46 | 47 | 1. NokiaFactory 48 | 2. MotorolaFactory 49 | 3. ... 50 | 51 | ## Client 52 |
53 | ``` 54 | Factory factory = new NokiaFactory() 55 | Mobile mobile = factory.createMobile(مشخصات موبایل، نام موبایل، مثل رنگ و ...) 56 | ``` 57 |
58 | ![Mobile Factory](http://yuml.me/679b958b) 59 | 60 | # مثال‌های واقعی 61 | - java.util.Calendar#getInstance() 62 | - java.util.ResourceBundle#getBundle() 63 | - java.text.NumberFormat#getInstance() 64 | - java.nio.charset.Charset#forName() 65 | - java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (Returns singleton object per protocol) 66 | 67 | # بیشتر بخوانید 68 | 1. کلاس SAXParserFactory 69 | 2. http://javapapers.com/design-patterns/factory-method-pattern/ 70 | 3. http://stackoverflow.com/questions/9963090/factory-pattern-vs-factorymethod-pattern 71 | 4. http://c2.com/cgi/wiki?FactoryMethodPattern 72 | 5. [Core J2EE Patterns - Data Access Object](http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Creational/SimpleFactory/Readme.md: -------------------------------------------------------------------------------- 1 |
2 | # Simple Factory (Idiom) 3 | 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. 4 | 2. Simple Factory یک الگوی طراحی واقعی نیست. اما به عنوان یک idiom برنامه‌نویسی بسیار رایج به کار گرفته می‌شود. 5 | 3. وصل کردن کد به کلاس‌های کانکرت، کد را شکننده و غیرقابل انعطاف می‌کند. 6 | 4. جایگزینی اپراتور new با متدهای createConcrete 7 | 5. می‌توانیم از متد استاتیک در این الگو استفاده کنیم. 8 | 6. استفاده از new باعث ایجاد نمونه از کلاس‌های کانکرت می‌شود. 9 | 7. استفاده از new یک نوع برنامه‌نویسی مرتبط با پیاده‌سازی‌ست تا یک برنامه‌نویسی مرتبط به اینترفیس. (کد شکننده، خطا پذیر، غیر قابل انعطاف می‌شود) 10 | 8. کلاس‌های کانکرت معمولاً بیشتر از یک بار یک مکان نمونه‌برداری (Instantiate) می‌شوند. 11 | 9. بنابراین در صورتی که بخواهیم تغییر بدهیم باید تمامی نمونه‌برداری‌ها را در مکان‌های مختلف را تغییر دهیم. که این کار طاقت‌فرسا، سخت و خطاپذیر است. 12 | 13 | # چرا از Simple Factory استفاده می‌کنیم؟ 14 | 1. Multiple Clinets neeeding same types of object 15 | 2. Ensure consistent object initialization. 16 | 17 | ![SimpleFactory](img/simplefactorystructure.gif) 18 | ![Simple Factory](img/SimpleFactory.jpg) 19 | ![Simple Factory Diagram](img/SimpleFactory.png) 20 | 21 | # Keywords: 22 | 1. Depenency 23 | 2. Loose Couple 24 | 3. Concrete classes (When you see `new`, think `concrete`) 25 | 4. Encapsulating object creation 26 | 27 | # مثال 28 |
29 | ```java 30 | public class PizzaStore { 31 | SimplePizzaFactory factory; 32 | 33 | public PizzaStore(SimplePizzaFactory factory) { 34 | this.factory = factory; 35 | } 36 | 37 | public Pizza orderPizza(String type) { 38 | Pizza pizza; 39 | 40 | pizza = factory.createPizza(type); 41 | 42 | pizza.prepare(); 43 | pizza.bake(); 44 | pizza.cut(); 45 | pizza.box(); 46 | 47 | return pizza; 48 | } 49 | 50 | } 51 | ``` 52 | 53 | ```java 54 | public class SimplePizzaFactory { 55 | 56 | // می‌توانیم این متود را استاتیک تعریف کنیم تا نیازی به ساخت شیء فکتوری نباشد و بتوانیم مستقیما از کلاس این متود را صدا بزنیم. 57 | public Pizza createPizza(String type) { 58 | Pizza pizza = null; 59 | 60 | if (type.equals("cheese")) { 61 | pizza = new CheesePizza(); 62 | } else if (type.equals("pepperoni")) { 63 | pizza = new PepperoniPizza(); 64 | } else if (type.equals("clam")) { 65 | pizza = new ClamPizza(); 66 | } else if (type.equals("veggie")) { 67 | pizza = new VeggiePizza(); 68 | } 69 | return pizza; 70 | } 71 | } 72 | ``` 73 | ![pizza Simple Factory](http://yuml.me/diagram/scruffy/class/330cfd3a.png) 74 | 75 | # اطلاعات بیشتر 76 | 1. [Simple Factory Pattern Side by Side with Abstract Pattern](http://www.c-sharpcorner.com/UploadFile/mosessaur/simplefactorypattern03012006124722PM/simplefactorypattern.aspx) 77 | 2. [Simple Factory](http://shamsmi.blogspot.fr/2007/08/simple-factory.html) 78 | 3. ص ۱۱۹ Head First Design Patterns 79 | 80 | -------------------------------------------------------------------------------- /Architecture/MVC/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | الگوی معماریِ MVC، سه مفهوم ذخیره‌سازی، نمایش و به‌روزآوری داده‌ها را به سه مؤلفه تقسیم می‌کند و به طوری که هر کدام به طور مجزا قابل تست باشند. 4 | 5 | # ساختار 6 | ![MVC class structure](http://i.msdn.microsoft.com/dynimg/IC114765.gif) 7 | 8 | - با توجه به ساختار کلاس MVC، کلاس‌های View , Controller به کلاس Model وابسته‌اند و کلاس مدل به هیچ کلاسی وابسته نیست. 9 | - مدل MVC پایه‌ترین الگو برای جداسازی منطق واسط کاربری و منطق کاری‌ست. 10 | 11 | 12 | # Separation of concerns (SoC) 13 | اطلاعات بیشتر در [ویکی‌پدیا](http://en.wikipedia.org/wiki/Separation_of_concerns) 14 | 15 | # مسئله 16 | - منطق UI بیشتر از منطق Business تغییر می‌کند، بنابراین اگر قرار باشد این دو منطق با هم کار کنند، هر وقت که خواستیم رابط کاربری را تغییر دهیم باید شیء‌ای را تغییر دهیم که در آن منطق Bussiness هم وجود دارد. و پس از هر تغییر کوچک در UI مجبوریم تمام Business logic را تست کنیم. 17 | - می‌خواهیم داده‌ها را به شکل‌های مختلفی نمایش دهیم. (رابط‌های گرافیکی متفاوت) 18 | - طراحی رابط کاربری دو قسمت داد ۱- نمایش (دریافت داده‌ها و نمایش آن‌ها) ۲- به‌روزآوری (تغییر داده‌ها که قسمت منطق کاری محسوب می‌شود.) 19 | - انجام تست خودکار روی رابط کاربری بسیار سخت‌تر از تست خودکار روی منطق کاری‌ست. 20 | 21 | ## Model (Domain Element) 22 | 1. حاوی تمام داده‌ها 23 | 2. چگونگی رفتار مدل 24 | 3. مدل به View و Controller ارجاع ندارد و تنها دستورات این دو کلاس را پردازش می‌کند. 25 | 26 | ## View 27 | 1. ارجاعی به کنترولر ندارد و تنها دستورات کنترولر را پردازش می‌کند. 28 | 2. ارجاعی به مدل دارد و داده‌ها را از مدل می‌گیرد تا آن‌ها را نمایش دهد. 29 | 30 | ## Controller 31 | 1. هم به View و هم به Model اشاره می‌کند. 32 | 33 | 34 | # گونه‌ها 35 | # Passive Model 36 | ![Passive Model](http://i.msdn.microsoft.com/dynimg/IC108622.gif) 37 | 38 | 39 | # Active Model 40 | ![Active Model Class Diagram](http://i.msdn.microsoft.com/dynimg/IC111180.gif) 41 | ![Behavior of the active model](http://i.msdn.microsoft.com/dynimg/IC100217.gif) 42 | 43 | # مشکلات 44 | ## پیچیدگی 45 | با جدا کردن سه مفهوم، متعاقباً پیچیدگی نیز بیشتر می‌شود. 46 | 47 | ## هزینهٔ به‌روزآوری‌های مکرر 48 | این الگو، مدل و رابط گرافیکی را از هم جدا می کند و متعاقباً با هر تغییر در رابط گرافیکی باید تغییر در مدل ایجاد کنیم و بالعکس. در صورتی که تعداداین تغییرات خیلی بالا باشد، هزینهٔ چنین تغییراتی زیاد می‌شود و راه حل این است که تغییرات متعدد را بسته‌بندی کنیم و در یکجا ارسال کنیم. 49 | 50 | # الگوهای مشتق شده 51 | ## Document-View 52 | در این الگو، View و Controller با هم ترکیب می‌شوند. 53 | 54 | # الگوهای مرتبط 55 | 1. Observer 56 | 57 | # مثال 58 | وقتی کاربر درجهٔ حرارت را به فارنهایت وارد کرده و دکمهٔ تبدیل به سانتیگراد را می‌زند آنگاه 59 | 60 | 1. کنترولر event مربوط به Button تبدیل درجه را دریافت می‌کند. 61 | 2. کنترولر ورودی را به مدل ارسال کرده و درخواست تبدیل به سانتیگراد را ارسال می‌کند. 62 | 3. مدل تبدیل را انجام می‌دهد. 63 | 4. کنترولر از View درخواست می‌کند تا نتیجه را نشان دهد. 64 | 5. کلاس View نتیجه را از مدل دریافت می کند. 65 | 6. کلاس View نتیجه را نمایش می‌دهد. 66 | 67 | # منابع 68 | 1. [OpenGL Windows GUI Application](http://www.songho.ca/opengl/gl_mvc.html) 69 | 2. [Microsoft Model-View-Controller](http://msdn.microsoft.com/en-us/library/ff649643.aspx) 70 | -------------------------------------------------------------------------------- /Creational/Builder/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | روند ساخت یک شیء پیچیده را از نمایش آن جدا می‌کند به طوری که یک روند ساخت مشترک می‌تواند برای ساخت انوع بازنمایی‌ها به کار گرفته شود. 4 | 5 | 6 | # ساختار 7 | ![Builder Pattern UML](http://javaobsession.files.wordpress.com/2010/06/builder-pattern1.png) 8 | 9 | 10 | # نکات طراحی 11 | موارد استفاده: 12 | - وقتی می‌خواهید روند ساخت (Construction) و نمایش (Representation) را مجزا و ایزوله کنید. 13 | - در صورتی که در روند ساخت یک شیء، بازنمایی‌های متفاوتی نیاز باشد. 14 | - وقتی نیاز به کنترل بیشتری برای روند ساخت اشیاء دارید. 15 | 16 | # اجزای الگو 17 | ## Builder 18 | - یک واسط مجرد برای ساخت اجزاء مختلف شیء تعریف می‌کند. 19 | 20 | ## ConcreteBuilder 21 | - با پیاده‌سازی واسط Builder اجزاء مختلف محصول را ایجاد و سرهم می‌کند. 22 | - همچنین پیاده‌سازی و بازنمایی شیء را در بر دارد. 23 | - رابطی برای بازگرداندن محصول آماده شده فراهم می‌کند. 24 | 25 | ## Director 26 | - با استفاده از واسط Builder شیء را می‌سازد. 27 | 28 | ## Product 29 | - نمایندهٔ شیء پیچیده‌ای‌ست که توسط ConcreteBuilder ایجاد می‌شود. می‌توان قسمت Product را هم به دو قسمت تبدیل کرد. 30 | 1. ProductInterface 31 | 2. ConcreteProduct 32 | 33 | # مثال ۱ (ساخت مبدل متن) 34 | 35 | ![TextConverter UML](http://jklunder.home.xs4all.nl/elisa/part05/Design%20Patterns/build096.gif) 36 | 37 | 1. ASCII Converter 38 | 2. TeX Converter 39 | 3. PDF Converter 40 | 41 | # مثال ۲ (ساخت خانه) 42 | مثال: فرض کنید بخواهیم انواع و اقسام خانه‌ها را طراح کنیم. روند طراحی در تمامی خانه‌ها یکسان است. که به کلاس‌های زیر تقسیم می‌شود: 43 | 44 | ##Builder 45 | 1. زیربنای آن را ایجاد می‌کنیم. 46 | 2. ساختار و اسکلت آن را ایجاد می‌کنیم. 47 | 3. سقف آن را می‌سازیم. 48 | 4. فضای داخل خانه را طراحی می‌کنیم. 49 | 50 | بنابراین برای طراحی همهٔ ساختمان‌ها یک رویهٔ یکسان داریم. بنابراین یک کلاس اینترفیس برای تمامی ساختمان‌ها با ۴ رویهٔ مذکور ایجاد می‌کنیم. که به آن Builder می‌گوییم. 51 | 52 | در این مثال: HouseBuilder 53 | 54 | ## ConcreteBuilder 55 | حال به تعداد انواع خانه‌ها، اینترفیس Builder را پیاده‌سازی می‌کنم، در این مثال می‌توانیم خانهٔ خشتی، خانهٔ گلی، خانهٔ برفی، خانهٔ فلزی، خانهٔ فلزی، خانهٔ چوبی، خانهٔ سیمانی را بسازیم. به هر یک از این کلاس‌ها ConcreteBuilder می‌گوییم: 56 | 57 | 1. KheshtiBuilder 58 | 2. GeliBuilder 59 | 3. BarfiBuilder 60 | 4. FeleziBuiler 61 | 62 | ## Director 63 | پیمانکار ساختمان، ساختمان‌ها را از طریق اینترفیس House ایجاد می‌کند. (ورودی: یک نوع خانه از نوع HouseBuilder) 64 | 65 | 1. ساخت زیربنا 66 | 2. ساخت اسکلت و ساختار ساختمان 67 | 3. ساخت سقف 68 | 4. طراحی درون ساختمان 69 | 70 | ## Product 71 | محصول نهایی، حاصل ترکیب تمامی مراحل ساخت یک خانه است. 72 | 1. خانهٔ گلی 73 | 2. خانهٔ خشتی 74 | 3. خانهٔ سیمانی 75 | و ... 76 | 77 | ## Client 78 | HouseBuilder builder = new KheshtiBuilder(); 79 | Director director = new Director(builder); 80 | director.construct(); 81 | 82 | # مثال‌های واقعی 83 | - java.lang.StringBuilder#append() (unsynchronized) 84 | - java.lang.StringBuffer#append() (synchronized) 85 | - java.nio.ByteBuffer#put() (also on CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer and DoubleBuffer) 86 | - javax.swing.GroupLayout.Group#addComponent() 87 | - All implementations of java.lang.Appendable 88 | 89 | # بیشتر بخوانید: 90 | - http://javapapers.com/design-patterns/builder-pattern/ 91 | 92 | 93 | -------------------------------------------------------------------------------- /Structural/Bridge/README.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | لایهٔ انتزاع را از لایهٔ پیاده‌سازی جدا می‌کند، بنابراین دو کلاس می‌توانند مستقلاً تغییر کنند. 4 | 5 | # ساختار 6 | ![Bridge UML](http://javaobsession.files.wordpress.com/2010/07/bridge-pattern1.png) 7 | 8 | # اجزاء 9 | - Abstraction 10 | - RefinedAbstraction 11 | - Implementor 12 | - ConcreteImplementor 13 | 14 | # نکات طراحی 15 | از این الگو زمانی استفاده کنید که 16 | - لایهٔ انتراع و پیاده‌سازی نباید در زمان اجرا به هم وابسته باشند. 17 | - لایهٔ انتزاع و پیاده‌سازی باید مستقلاً قابل گسترش و توسعه باشند. 18 | - جزئیات لایهٔ پیاده‌سازی باید از دیدگاه کارخواه مخفی بماند. 19 | - تغییرات در لایهٔ پیاده‌سازی (که لایهٔ انتزاع را پیاده‌سازی می‌کند) نباید منجر به کامپایل مجدد کدِ کارخواه شود. 20 | 21 | برای طراحی این الگو، در کلاس انتزاعی، یک نمونه از کلاس پیاده‌سازی نگه می‌داریم. در این صورت قادر خواهیم بود که در زمان اجرا، پیاده‌سازی‌های متفاوتی را برای کلاس انتزاعی در نظر بگیریم. به کد زیر توجه کنید: 22 |
23 | ```java 24 | Implementation implementation = new FirstImplementation(); 25 | Abstraction abstraction = new Abstraction( implementation ); 26 | abstraction.operation(); 27 | ``` 28 |
29 | # مثال 30 | فرض کنید که می‌خواهیم کلاس قطارها را طراحی کنیم. دو نوع قطار داریم. قطارهای معمولی و قطارهای یک ریلی. 31 |
32 | ```c++ 33 | class Train { 34 | public: 35 | virtual void move() = 0; 36 | }; 37 | 38 | class MonoRail : public Train { 39 | public: 40 | virual void move() { /* use one track */ } 41 | }; 42 | 43 | class Rail : public Train { 44 | public: 45 | virtual void move() { /* use twi track */ } 46 | }; 47 | ``` 48 |
49 | فرض کنید بعد از پیاده‌سازی دو قطار بالا به قطارهای برقی هم نیاز پیدا کنیم. آنگاه مجبوریم کلاس‌ها را به شکل زیر تغییر دهیم: 50 |
51 | ```c++ 52 | class Train { 53 | public: 54 | virtual void move() = 0; 55 | }; 56 | 57 | class MonoRail : public Train { 58 | public: 59 | virtual void move() { /* use one track */ } 60 | }; 61 | 62 | class ElectronicMonoRail : public MonoRail { 63 | public: 64 | virtual void move() { /* electronic engine on one track */ } 65 | }; 66 | 67 | class DiselMonoRail : public MonoRail { 68 | public: 69 | virtual void move() { /* disel engine on one track */ } 70 | }; 71 | 72 | class Rail { 73 | public: 74 | virtual void move() { /* use two tracks */ } 75 | }; 76 | 77 | class ElectricRail : public Rail { 78 | virtual void move() { /* use electric engine on two tracks */ } 79 | }; 80 | 81 | class DiselRail : public Rail { 82 | virtual void move() { /* use disel engine on two tracks */ } 83 | }; 84 | ``` 85 |
86 | کد بالا قابل نگهداری نیست و فاقد قابلیت استفادهٔ مجدد است. کد زیر الگوی Bridge را به کد بالا اعمال می‌کند و دو لایهٔ انتزاع `train transport` و `acceleration` را از هم جدا می‌کند. 87 |
88 | ```c++ 89 | class Train { 90 | public: 91 | virtual void move( Accelerable* engine ) = 0; 92 | }; 93 | 94 | class Accelerable { 95 | public: 96 | virtual void acclerate(); 97 | }; 98 | 99 | class MonoRail : public Train { 100 | public: 101 | virtual void move( Accelerable* engine ) { 102 | engine->acclerate(); //engine is pluggable (runtime dynamic) 103 | } 104 | }; 105 | 106 | class Rail : public Train { 107 | public: 108 | virtual void move( Accelerable* engine ) { 109 | engine->acclerate(); // engine is pluggable (runtime dynamic) 110 | } 111 | }; 112 | 113 | class ElectricEngine : public Accelerable { } 114 | class DiselEngine : public Accelerable{ } 115 | ``` 116 | -------------------------------------------------------------------------------- /Behavioural/TemplateMethod/README.md: -------------------------------------------------------------------------------- 1 |
2 | # تعریف 3 | استخوان‌بندی و شالودهٔ اصلی عملیات الگوریتم را تعریف می‌کند، و پیاده‌سازی هر مرحله را به زیرکلاس‌ها می‌سپارد. این الگو، به زیرکلاس‌ها این اختیار را می‌دهد که تا خودشان، مراحل الگوریتم را پیاده کنند بدون اینکه ساختار الگوریتم را تغییر دهند. 4 | 5 | 6 | # ساختار 7 | ![UML Structure](http://yuml.me/77419b3e) 8 | 9 | 10 | # نکات طراحی 11 | در این الگو ساختار اصلی الگوریتم را در متدی به نام TemplateMethod طراحی می‌کنیم. این متد دارای یک سری عملیات اولیه (Primitive Operations) است. این متد را دسترسی پابلیک می‌دهیم و تمامی عملیات اولیه را ابسترکت و protected می‌کنیم تا کلاس‌های کانکرت به دلخواه خود توابع اولیهٔ مناسب خود را طراحی کنند. 12 | - این الگو کنترل بیشتری نسبت به الگوی Strategy نسبت به الگوریتم‌های متفاوت دارد. 13 | - الگوی استراتژی از Composition استفاده می‌کد و الگوی تمپلیت متد از وراثت. الگوی استراتژی flexibility بیشتری نسبت به تمپلیت متد دارد. 14 | - الگوی تملیت متد با استفاده از متدهای Hook برای ساخت فریم‌ورک مناسب است. 15 | - الگوی طراحی تملیت متد دارای Depenency است در صورتی که الگوی طراحی استراتژی به دلیل استفاده از کامپوزیشن عاری از Dependency است. 16 | - الگوی طراحی تمپلیت متد از اصل هالیوود استفاده می‌کند، اصل هالیوود می‌گوید: با ما تماس نگیرید، ما با شما تماس می‌گیریم. 17 | - [Hollywood principle - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/Hollywood_principle) 18 | - این الگو مراحل را خود تعریف می‌کند اما در پیاده‌سازی هر یک از مراحل اختیار را به زیرکلاس‌ها می‌دهد. 19 | - این الگو نمونه‌ای از Code Reuse است. 20 | - هوک‌ها متدهایی هستند که کاری انجام نمی‌دهند یا عمل پیشفرضی در کلاس ابسترکت انجام می‌دهند. هوک‌ها «ممکن» است توسط زیرکلاس‌ها override شوند و عمل پیشفرض آن‌ها تغییر کند. 21 | - برای جلوگیری override کردن متد تمپلیت توسط زیرکلاس‌ها، متند تمپلیت را final کنید. 22 | - الگوی طراحی Factory Method نیز حالت خاصی از الگوی طراحی Template Method است. 23 | 24 | 25 | # اجزاء الگو 26 | ## AbstractClass 27 | 1. عملیات اولیه را به صورت ابسترکت «معرفی» می‌کند. البته اگر عملیاتی اختیاری‌ست یعنی کلاس‌های کانکرت می‌توانند آن را override کنند یا نه، می‌توان چنین عملیات اختیاری را به صورت Hook تعریف کرد. 28 | 2. متد TemplateMethod را که ساختار الگوریتم است را «پیاده‌سازی» می‌کند. این متد در کلاس‌های کانکرت Override نمی‌شود. (final در جاوا) 29 | 30 | ## ConcreteClass 31 | هر کانکرت کلاسی، عملیات اولیه را مطابق کلاس خود پیاده سازی می‌کند. 32 | 33 | # Hook 34 | 1. متدهای start و stop و init و destroy در کلاس Applet در جاوا. 35 | 2. متد paint در کلاس JFrame در کتابخانهٔ جاوا. 36 | 37 | # مثال (تولید کنندهٔ سند) 38 | ![DocumentGenerator](http://yuml.me/40441c19) 39 | روال تولید سند برای انواع و اقسام سندها یکسان است: 40 | 41 | 1. فسمت Header سند را تولید کن. 42 | 2. قسمت بدنهٔ سند را تولید کن. 43 | 3. جزئیات سند را تولید کن. 44 | 45 | اما پیاده‌سازی هر یک از این روال‌ها برای ساخت PDF و HTML و Doc و ... متفاوت است. بنابراین می توانیم از الگوی طراحی TemplateMethod استفاده کنیم. 46 | 47 | # مقایسهٔ سه الگوی طراحی 48 | 1. Template Method: زیرکلاس‌ها تصمیم می گیرند که مراحل اجرای الگوریتم را چطور پیاده سازی کنند. 49 | 2. Strategy: رفتارهای قابل تغییر را کپسوله می‌کند و از واگذاری و دلگیشن استفاده می‌کند تا در زمان اجرا تصمیم بگیرد که کدام رفتار اعمال شود. 50 | 3. Factory Method: زیرکلاس‌ها تصمیم می‌گیرند که کدام یک از کلاس‌های کانکرت، ایجاد شوند. 51 | 52 | # مثال‌های واقعی 53 |
54 | - All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer. 55 | - All non-abstract methods of java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap. 56 | - javax.servlet.http.HttpServlet, all the doXXX() methods by default sends a HTTP 405 "Method Not Allowed" error to the response. You're free to implement none or any of them. 57 | 58 | # بیشتر 59 | 1. [الگوریم مرتب‌سازی به وسیلهٔ الگوی طراحی Template Method](http://sourcemaking.com/design_patterns/template_method/cpp/2) 60 | 2. [Template method design pattern in java](http://javapostsforlearning.blogspot.com/2013/03/template-method-design-pattern-in-java.html) 61 | -------------------------------------------------------------------------------- /Behavioural/Interpreter/RomanNumeralInterpreter/C++/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Adopted from http://sourcemaking.com/design_patterns/interpreter/cpp/1 3 | */ 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Thousand; 10 | class Hundred; 11 | class Ten; 12 | class One; 13 | 14 | class RomanNumeralInterpreter { 15 | public: 16 | RomanNumeralInterpreter(); 17 | RomanNumeralInterpreter( int ) {} 18 | 19 | int interpret( char* ); // interpret for client 20 | virtual void interpret( char* input, int &total ) { 21 | int index; 22 | index = 0; 23 | if ( !strncmp( input, nine(), 2 ) ) { 24 | total += 9 * multiplier(); 25 | index += 2; 26 | } else if ( !strncmp( input, four(), 2 ) ) { 27 | total += 4 * multiplier(); 28 | index += 2; 29 | } else { 30 | if ( input[0] == five() ) { 31 | total += 5 * multiplier(); 32 | index = 1; 33 | } 34 | else { 35 | index = 0; 36 | } 37 | 38 | for ( int end = index + 3; index < end; index++ ) { 39 | if ( input[index] == one() ) 40 | total += 1 * multiplier(); 41 | else 42 | break; 43 | } 44 | } 45 | strcpy( input, &(input[index]) ); 46 | } 47 | protected: 48 | // Cannot be pure virtual fuction, because client asks for instance 49 | virtual const char one() {} 50 | virtual const char* four() {} 51 | virtual const char five() {} 52 | virtual const char* nine() {} 53 | 54 | virtual int multiplier() {} 55 | private: 56 | RomanNumeralInterpreter* thousands; 57 | RomanNumeralInterpreter* hundreds; 58 | RomanNumeralInterpreter* tens; 59 | RomanNumeralInterpreter* ones; 60 | }; 61 | 62 | class Thousand : public RomanNumeralInterpreter { 63 | public: 64 | Thousand( int ) : RomanNumeralInterpreter( 1 ) {} 65 | protected: 66 | const char one() { 67 | return 'M'; 68 | } 69 | 70 | const char* four() { 71 | return ""; 72 | } 73 | 74 | const char five() { 75 | return '\0'; 76 | } 77 | 78 | const char* nine() { 79 | return ""; 80 | } 81 | 82 | int multiplier() { 83 | return 1000; 84 | } 85 | }; 86 | 87 | class Hundred : public RomanNumeralInterpreter { 88 | public: 89 | Hundred( int ) : RomanNumeralInterpreter( 1 ) {} 90 | protected: 91 | const char one() { 92 | return 'c'; 93 | } 94 | 95 | const char* four() { 96 | return "CD"; 97 | } 98 | 99 | const char five() { 100 | return 'D'; 101 | } 102 | 103 | const char* nine() { 104 | return "CM"; 105 | } 106 | 107 | int multiplier() { 108 | return 100; 109 | } 110 | }; 111 | 112 | class Ten : public RomanNumeralInterpreter { 113 | public: 114 | Ten( int ) : RomanNumeralInterpreter( 1 ) {} 115 | protected: 116 | const char one() { 117 | return 'X'; 118 | } 119 | 120 | const char* four() { 121 | return "XL"; 122 | } 123 | 124 | const char five() { 125 | return 'L'; 126 | } 127 | 128 | const char* nine() { 129 | return "XC"; 130 | } 131 | 132 | int multiplier() { 133 | return 10; 134 | } 135 | }; 136 | 137 | class One : public RomanNumeralInterpreter { 138 | public: 139 | One( int ) : RomanNumeralInterpreter( 1 ) {} 140 | protected: 141 | const char one() { 142 | return 'I'; 143 | } 144 | 145 | const char* four() { 146 | return "IV"; 147 | } 148 | 149 | const char five() { 150 | return 'V'; 151 | } 152 | 153 | const char* nine() { 154 | return "IX"; 155 | } 156 | 157 | int multiplier() { 158 | return 1; 159 | } 160 | }; 161 | 162 | RomanNumeralInterpreter::RomanNumeralInterpreter() { 163 | // Use 1-arg ctor to avoid infinite loop 164 | thousands = new Thousand( 1 ); 165 | hundreds = new Hundred( 1 ); 166 | tens = new Ten( 1 ); 167 | ones = new One( 1 ); 168 | } 169 | 170 | int RomanNumeralInterpreter::interpret( char* input ) { 171 | int total; 172 | total = 0; 173 | thousands->interpret( input, total ); 174 | hundreds->interpret( input, total ); 175 | tens->interpret( input, total ); 176 | ones->interpret( input, total ); 177 | 178 | if ( strcmp( input, "" ) ) //if input was invalid return 0 179 | return 0; 180 | 181 | return total; 182 | } 183 | 184 | int main() { 185 | RomanNumeralInterpreter interpreter; 186 | char input[20]; 187 | cout << "Enter Roman Numeral: " ; 188 | while( cin >> input ) { 189 | cout << " interpretation is " << interpreter.interpret( input ) << endl; 190 | cout << "Enter Roman Numeral: "; 191 | } 192 | } 193 | 194 | 195 | -------------------------------------------------------------------------------- /Behavioural/Command/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # هدف 4 | درخواست را به عنوان یک شیء کپسوله می‌کند، از این رو اجازه می‌دهد تا بتوانید کارخوه‌ها را با درخواست‌ها، صف‌ها و یا لاگ‌های متفاوت پارامتری کنید. 5 | 6 | # ساختار 7 | # Class Digaram 8 | ![Class Digaram](http://javaobsession.files.wordpress.com/2010/07/command-pattern.png) 9 | 10 | # Sequence Diagram 11 | ![Sequence Diagram](http://javaobsession.files.wordpress.com/2010/07/command-pattern-sd.png) 12 | 13 | # نکات طراحی 14 | - کپسوله کردن درخواست‌ها 15 | - پارامتری کردن کلاینت به طوری که بتواند درخواست‌های متفاوتی را دریافت کند. برای مثال پیشخدمت در طول روز درخواست‌های متفاوتی را دریافت می‌کند و یا در مثال ریموت کنترل، کنترلر می‌تواند درخواست‌های متفاوتی را دریافت کند. 16 | 17 | از این الگو زمانی استفاده کنید که 18 | - نیاز به پشتیبانی از گزارش‌نویسی (logging) دارید. 19 | - لازم است تاریخچه را مدیریت کنید. (مثل عملیات undo/redo) 20 | - نیاز است تا از تراکنش‌ها پشتیبانی کنید. 21 | - نیاز به callback دارید. 22 | - نیاز است تا درخواست‌ها در زمان‌های متفاوت و یا در ترتیب‌های متفاوت (صف، پشته و ...) هندل شوند. 23 | - منبع درخواست باید از شیء‌ای که واقعاً درخواست را هندل می‌کند، جدا (دیکوپلینگ) شوند. 24 | 25 | # اجزاء الگو 26 | - Command: رابطی برای اجرای عملیات بیان می‌کند. 27 | - ConcreteCommand 28 | - Client: اشیاء ConcreteCommand را می‌سازد و receiverهای آن‌ها را تنظیم می‌کند. 29 | - Invoker: از Command می‌خواهد که درخواست‌اش را حمل کند. 30 | - Receiver 31 | 32 | # کاربردها 33 | 1. Thread pools: رجوع شود به java.lang.Runnable 34 | 2. Transactional behavior: قابل برگشت بودن عملیات 35 | 3. Wizards: به تأخیر انداختن عملیات 36 | 4. Macro Recording: می‌توانیم عملیات متفاوت و پشت سرهم را ضبط کنیم و سپس یکباره آن‌ها را اجرا کنیم. مثل ماکروها در ویرایشگرهای vim و Emacs و یا ماکروهای IDEها. 37 | 5. Multi-level undo: چون عملیات به صورت شیء در پشته ذخیره می‌شود هر گاه کاربر بخواهد به اندازهٔ چند مرحله Undo کند، به راحتی با pop کردن اشیاء از پشته و اجرای عملیات undo امکان‌پذیر است. 38 | 6. Job queue: تمامی اشیاء command را وارد صف می‌کنیم و هر کدام را از صف خارج کرده و یک نخ به آن‌ها اختصاص می‌دهیم تا کار آن‌ها تمام شود. 39 | 40 | # Null Object 41 | اگر برای اسلاتی هیچ عملیاتی در نظر نداشته باشیم، می‌توانیم یک شیء Null به نام NoCommand درست کنیم و آن را به اسلات مورد نظر متصل کنیم. 42 | 43 | # مثال ۱ (پیاده‌سازی عملیات تراکنشی) 44 | اگر بخواهیم چندین فرآیند را به صورت تراکنش انجام دهیم این الگوی طراحی می‌تواند به ما کمک کند. برای مثال فرض کنید که بخواهیم کارهای زیر را انجام دهیم: 45 | 1. یک رکورد در دیتابیس ایجاد کن. 46 | 2. سرویسی را صدا بزن تا تمامی رکوردهای مرتبط را به روزرسانی کند. 47 | 3. سرویس دیگری را صدا بزن تا عملیات را لاگ کند. 48 | برای انجام این عملیات تراکنش گونه، می‌توانیم هر عمل را به صورت یک ConcreteCommand طراحی کنیم. که همهٔ این عملیات undo دارند. در آخر هر مرحله، آن کامند را وارد پشته می‌کنیم. اگر عملیات در مرحله‌ای شکست بخورد، سپس کامندها را یکی یکی از پشته خارج می‌کنیم و undo را روی آن‌ها اجرا می‌کنیم. 49 | 50 | منبع: http://stackoverflow.com/a/12153801/225052 51 | 52 | # مثال ۲ (ریموت کنترل) 53 | فرض کنید که کلی وسیله داریم که هر کدام اینترفیس مخصوص به خود برای روشن و خاموش شدن و به کار افتادن و عملیات‌های مختلف را داشته باشند. 54 | 55 | 1. پنکه : روشن/خاموش/افزایش سرعت/کاهش سرعت 56 | 2. تلویزیون: روشن/خاموش/شبکهٔ بعدی/شبکهٔ قبلی 57 | 3. چراغ: روشن/خاموش 58 | 4. استریو: روشن/خاموش/فعال کردن سی‌دی/فعال کردن دی‌وی‌دی/فعال کردن رادیو 59 | 60 | می‌خواهیم یک کنترل از راه دور برای این دستگاه‌ها طراحی کنیم. 61 | 1. نیازی نیست که کنترلر اینترفیس دستگاه‌های مختلف را بداند. فقط کافی‌ست که درخواست خودش را برای این دستگاه‌ها ارسال کند. 62 | 2. با چنین طراحی‌ای هر گاه دستگاه جدیدی اضافه شود به راحتی می توان دکمهٔ جدیدی برای کنترل آن در کنترلر تعریف کرد. 63 | 3. الگوی طراحی Command درخواست کنندهٔ عمل را از انجام‌دهندهٔ عمل جدا می‌کند. 64 | 4. برای انجام چنین کاری «شیء فرمان» تعریف می‌کنیم: در خواست‌ها را کپسوله برای اشیاء مختلف کپسوله می‌کنیم مثلاً اشیائی به صورت زیر خواهیم داشت: 65 | 1. ضبط صوت را روشن کن (یک شیء است) 66 | 2. لامپ را خاموش کن (شیء) 67 | 3. تلویزیون را خاموش کن (شیء) 68 | 69 | # مثال ۳ (رستوران) 70 | 1. مشتری به پیشخدمت درخواست پخت غذای مخصوصی را می‌دهد. ‍`createOrder()` 71 | 2. پیشخدمت درخواست را از مشتری گرفته `takeOrder()` و به روی میز سرآشپزها بگذارد `orderUp()`. 72 | 3. سرآشپز از روی درخواست غذای مورد نظر مشتری را تهیه می‌کند. `makeBurger()` و `makeShake()` 73 | 74 | در این روش پیشخدمت از جزئیات با خبر نیست و فقط دستور مشتری را به سرآشپزها منتقل می‌کند. 75 | 76 | # مثال‌های واقعی 77 |
78 | - All implementations of java.lang.Runnable 79 | - All implementations of javax.swing.Action 80 | -------------------------------------------------------------------------------- /Behavioural/Strategy/Readme.md: -------------------------------------------------------------------------------- 1 |
2 | # هدف 3 | خانواده‌ای از الگوریتم ها را تعریف می‌کند، هر یک را کپسوله می‌کند و آن‌ها را جابه‌جا پذیر می‌کند. الگوی استراتژی اجازه می‌دهد که الگوریتم‌ها مستقل از کارخواهی که از آن‌ها استفاده می‌کند، تغییر کنند. 4 | 5 | # نام دیگر 6 | Policy Pattern 7 | 8 | # ساختار 9 | ![Strategy Pattern](http://yuml.me/diagram/scruffy;/class/// Non-specific Strategy Class Diagram, [Caller]<>->[<>;Algorithm], [<>;Algorithm]^-.-[ConcreteAlgorithm1], [<>;Algorithm]^-.-[ConcreteAlgorithm2]) 10 | 11 | # Keywords 12 | - Behavioral Pattern 13 | - Strategy at runtime (Change Behavior at Runtime) 14 | - Composition (HAS-A is better than IS-A) 15 | 16 | # نکات طراحی 17 | - در الگوی طراحی استراتژی سعی می‌کنیم که رفتارهای غیرثابت و متفاوت `(استراتژی‌های متفاوت)` را از کلاس خارج کنیم و به طور مستقل آن‌ها را کپسوله کنیم. در این صورت هر کلاس، هر کدام از الگوریتم‌هایی که نیاز داشته باشند را درون خود استفاده می‌کنند. همچنین این الگو اجازه می‌دهد تا هر یک از کلاس‌ها هر وقت که بخواهند، `استراتژی` خودشان را تغییر دهند. 18 | 19 | - به انتخاب و تغییر رفتار (استراتژی) مناسب در زمان اجرا strategy at runtime می‌گوییم. 20 | - رفتارها و `استراتژی‌هایی` که طول ساختار وراثتی کلاس تغییر می‌کند را مشخص کنید و آن رفتارها را از کلاس خارج کنید. و آن‌ها را جداگانه کپسوله کنید. 21 | - آنچه که تغییر می‌کند را از آنچه ثابت می‌ماند جدا کنید. 22 | - مزیت `استراتژی` این است که اگر بخواهیم در طول توسعهٔ نرم‌افزار رفتارها و `استراتژی‌های` جدیدی تعریف کنیم، نیازی به تغییر کلاس‌های اصلی که از این رفتارهای استفاده می‌کنند نداریم. 23 | 24 | 25 | # اجزاء 26 | 1. Strategy 27 | 2. ConcreateStrategy 28 | 3. Context 29 | 30 | # Client Code 31 | 32 |
33 | ```java 34 | Context context = new Context(new ConcreateStrategy1()); 35 | context.AlgorithmInterface(); 36 | ``` 37 |
38 | 39 | #مثال ۱ 40 | فرض کنید که کلاسی داریم به نام `Car()` با متودی به نام `run()` آنگاه می‌توانیم آن را به صورت زیر پیاده کنیم: 41 | 42 |
43 | ```java 44 | Car car = new Car(); 45 | car.run(); 46 | ``` 47 |
48 | 49 | حالا اگر بخواهیم هنگامی که ماشین روشن است، رفتار ماشین را تغییر دهیم چه کار کنیم؟ مثلاً بخواهیم در نرم‌افزار بازی دکمهٔ `Boost‍` را شبیه‌سازی کنیم. چندین روش وجود دارد یکی این که از متغییرهای شرطی و ... استفاده کنیم راه دیگر استفاده از `الگوی طراحی استراتژی` هست. مثلاً‌ می‌تواین حین بازی موتور میاشین را عوض کنیم!! مثال: 50 |
51 | ```java 52 | Class Car() 53 | { 54 | this.motor = new Motor(this) 55 | 56 | // passing "this" is important for the motor so it knows what it is running 57 | 58 | method run() 59 | { 60 | this.motor.run() 61 | } 62 | 63 | method changeMotor(motor) 64 | { 65 | this.motor=motor 66 | } 67 | 68 | } 69 | ``` 70 |
71 | ## مثال ۲ 72 | فرض کنید که یک کارخانهٔ تلفن گوشی همراه داریم. که انواع و اقسام گوشی‌ها را تولید می‌کند. خب برای پیاده‌سازی کلاس‌های این گوشی‌ها چه کنیم؟ 73 | 74 | اولی: آیا می‌توانیم تمامی رفتارهای مختلف و قابلیت‌های گوشی‌های مختلف رو در کلاس مادر تعریف کنیم؟ 75 | 76 | دومی: خیر، چون همهٔ‌ گوشی‌ها همهٔ قابلیت‌ها را پیاده نمی‌کنند. بعضی از گوشی‌ها دوربین دارند بعضی ندارند. بعضی رادیو دارند بعضی ندارند. بعضی قابلیت اتصال به کامپیوتر دارند و بعضی ندارند. 77 | 78 | اولی: خب حالا چه کار کنیم؟ 79 | 80 | دومی: خب همهٔ قابلیت‌ها را در کلاس مادر تعریف نمی‌کنیم. سعی می‌کنیم قابلیت‌ها را در طول ساختار وراثت به سیستم اعمال کنیم. 81 | 82 | اولی: اولاً‌ این روش معقولانه‌ای نیست چون برای اضافه کردن هر رفتار و قابلیت جدید باید کلاس و ساختار وراثت را دچار تغییر کنیم. دوم این که باعث ایجاد `کدهای تکراری` می‌شود. 83 | 84 | دومی: راهکار چیست؟ 85 | 86 | اولی: استفاده از `الگوی استراتژی` یعنی رفتارهای متغیر را از رفتارهای ثابت جدا کنیم و رفتارهای متغیر را ساختار وراثتی کلاس خارج کنیم. و آن‌ها را کپسوله کنیم. 87 | 88 | # مثال ۳ 89 | فرض کنید که قرار است کلاسی بسازیم که آرایهٔ ورودی را مرتب کند. می‌خواهیم بر اساس نوع داده‌ها، ترتیب داده‌ها و پراکندگی داده‌ها الگوریتم مرتب‌سازی مناسب را در run-time اعمال کنیم. برای انجام چنین کاری می‌توانیم از الگوی استراتژی استفاده کنیم. 90 | 91 | # مثال‌های واقعی 92 | 93 |
94 | - java.util.Comparator#compare(), executed by among others Collections#sort(). 95 | - javax.servlet.http.HttpServlet, the service() and all doXXX() methods take HttpServletRequest and HttpServletResponse and the implementor has to process them (and not to get hold of them as instance variables!). 96 | - javax.servlet.Filter#doFilter() 97 | 98 |
99 | 100 | # اطلاعات بیشتر 101 | 102 |
103 | 1. [How does the Strategy Pattern work?](http://stackoverflow.com/questions/91932/how-does-the-strategy-pattern-work) 104 | 2. ص ۳۴۹ کتاب Gang of for 105 | 3. ص ۱۲ کتاب Head First Design Pattern 106 | 4. [Encapsulate a family of algorithms using Strategy Pattern](http://taskinoor.wordpress.com/2011/04/03/encapsulate_algorithm_strategy/) یک مثال خیلی خوب 107 | 108 | 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Design-Patterns 2 | =============== 3 |
4 | # هدف ما 5 | ما می‌خواهیم مجموعهٔ به-روز و کاملی از الگوهای طراحی را ایجاد کنیم. مجموعه‌ای که شامل مثال‌های متنوع و کاربردی از تمام زبان‌های برنامه‌نویسی باشد. 6 | 7 | # همکاری 8 | برای شروع به همکاری 9 | - مخزن را [فورک کنید](https://help.github.com/articles/fork-a-repo)، یک انشعاب (Branch) درست کنید، شروع به کار کنید و کارتان را به مخزن اعمال کنید، آن انشعاب را به گیت‌هاب push کنید، و [درخواست Pull را ارسال کنید](https://help.github.com/articles/creating-a-pull-request). 10 | - یا درخواست‌تان را از طریق [issue](https://github.com/khajavi/Design-Patterns/issues) بیان کنید. 11 | - برای رسم دیاگرام‌های UML از نرم‌افزار [Visual Paradigm](http://www.visual-paradigm.com/download/vpuml.jsp?edition=ce) استفاده شده است، در صورتی که می‌خواهید دیاگرامی اضافه کنید، برای هماهنگی تصاویر پیشنهاد می‌شود از همین نرم‌افزار استفاده کنید. 12 | 13 | # استفاده از مثال‌ها 14 | - هر الگو یک پوشه به نام Classic دارد که نام کلاس‌های آن از دیاگرام‌های کتاب GoF گرفته شده است. مثال‌های Classic ایدهٔ اولیه برای الگوها هستند و برای یادگیری ساختار الگوها مناسبند. اما برای آشنایی با کاربرد آن‌ها مثال‌های دیگری غیر از Classic درون پوشهٔ هر الگو گنجانده شده است. 15 | - برای سادگی بیشتر در مثال‌های C++، مباحث مدیریت حافظه و جلوگیری از Memory Leak مطرح نشده است از این رو در صورتی که می‌خواهید این الگوها را در یک پروژهٔ واقعی استفاده کنید، حواستان باشد که اشیاء را در حافظه مدیریت کنید. 16 | 17 |
18 | 19 | ## Creational Patterns 20 |
21 | - [Abstract Factory](Creational/AbstractFactory): بدون مشخص کردن کلاس‌های کانکرت، واسطی برای ساخت خانواده‌ای از اشیاء وابسته یا مرتبط با یکدیگر فراهم می‌کند. 22 | 23 | - [Builder](Creational/Builder): روند ساخت یک شیء پیچیده را از نمایش آن جدا می‌کند به طوری که یک روند ساخت مشترک می‌تواند برای ساخت انوع بازنمایی‌ها به کار گرفته شود. 24 | 25 | - [Factory Method](Creational/FactoryMethod): واسطی برای ساخت اشیاء ایجاد می‌کند، اما به زیرکلاس‌ها اجازه می‌دهد که تصمیم بگیرند که چه کلاسی را نمونه‌سازی کنند. این الگو اجازه می‌دهد تا نمونه‌برداری کلاس، به زیرکلاس‌ها معوق شود. 26 | 27 | - [Prototype](Creational/Prototype): انواع اشیائی که باید ساخته شوند را با استفاده از یک نمونهٔ اولیه، مشخص می‌کند و اشیاء جدید را با کپی کردن این نمونهٔ اولیه تولید می‌کند. 28 | 29 | - [Singleton](Creational/Singleton): تضمین می‌کند که کلاس تنها یک نمونه داشته باشد و دسترسی سراسری برای آن فراهم می‌کند. 30 | 31 |
32 | 33 | ## Structural Patterns 34 |
35 | - [Adapter](Structural/Adapter): یک واسط را به واسط مورد نظر کلاینت تبدیل می‌کند و اجازه می‌دهد تا کلاس‌ها با اینترفیس‌های متفاوت و ناسازگار با یکدیگر کار کنند. 36 | 37 | - [Bridge](Structural/Bridge): لایهٔ انتزاع را از لایهٔ پیاده‌سازی جدا می‌کند، بنابراین دو کلاس می‌توانند مستقلاً تغییر کنند. 38 | 39 | - [Composite](Structural/Composite): اشیاء را درون ساختار درختی ترکیب می‌کند تا سسله-مراتب جز-کل را ارائه کند. الگوی کامپوزت به کارخواه‌ها اجازه می‌دهد تا با اشیاء تکی و با اشیائی که ترکیبی از اشیاء هستند، به یک صورت رفتار کند. 40 | 41 | - [Decorator](Structural/Decorator): وظایف و قابلیت‌های بیشتری را به صورت داینامیک به شیء اضافه می‌کند. دکوریتورها برای توسعهٔ رفتارها و قابلیت‌ها روش انعطاف‌پذیر جایزینی را به جای زیرکلاس‌سازی ارائه می‌دهند. 42 | 43 | - [Facade](Structural/Facade): واسط یکپارچه‌ای را برای مجموعه‌ای از واسط‌ها در زیر سیستم، ارائه می‌دهد. این الگو واسط سطح-بالاتری را تعریف می‌کند که استفاده از زیرسیستم را ساده‌تر می‌کند. 44 | 45 | - [Flyweight](Structural/Flyweight): استفادهٔ دوبارهٔ بسیاری از اشیاء fine-grain را با اشتراک آن‌ها در سیستم، آسان می‌کند. 46 | 47 | - [Proxy](Structural/Proxy): برای کنترل دسترسی به اشیاء، نماینده یا نگهدارنده‌ای برای آن‌ها ارائه می‌کند. 48 | 49 |
50 | 51 | ## Behavioural Patterns 52 |
53 | - [Chain Of Responsibility](Behavioural/ChainOfResponsibility): با دادن بیشتر از یک شیء برای هندل کردن درخواست از جفتگری (کوپلینگ) فرستندهٔ درخواست و گیرندهٔ درخواست اجتناب می‌کند. اشیاء گیرنده را زنجیر می‌کند و درخواست را در امتداد زنجیر گذر می‌دهد تا زمانی که یکی از اشیاء آن را هندل کند. 54 | 55 | - [Command](Behavioural/Command): درخواست را به عنوان یک شیء کپسوله می‌کند، از این رو اجازه می‌دهد تا بتوانید کارخوه‌ها را با درخواست‌ها، صف‌ها و یا لاگ‌های متفاوت پارامتری کنید. 56 | 57 | - [Interpreter](Behavioural/Interpreter): یک بازنمایی برای گرامر زبان داده شده تعریف می‌کند و مفسر توسط این باز نمایی، جملات زبان را تفسیر می کند. 58 | 59 | - [Iterator](Behavioural/Iterator): روشی برای دستری به عناصر یک شیء اگریگیت فراهم می‌کند بدون اینکه اصول پیاده‌سازی و ساختمان دادهٔ لایهٔ زیرین اگریگیت را نمایش دهد. 60 | 61 | - [Mediator](Behavioural/Mediator): شیء‌ای را تعریف می‌کند که نحوهٔ ارتباط بین مجوعه‌ای از اشیاء را کپسوله می‌کند. این الگو با جلوگیری ارتباط صریح بین اشیاء از جفتگری ضعیف (loose coupling) پشتیبانی می‌کند. 62 | 63 | - [Memento](Behavioural/Memento): بدون تخلف از کپسوله‌سازی، وضعیت داخلی شیء ضبط و استخراج می‌کند از این رو شیء بعداً می‌تواند به این حالت برگردد. 64 | 65 | - [Observer](Behavioural/Observer): وابستگی یک-به-چند بین اشیاء تعریف می‌کند بنابراین وقتی یک شیء وضعیت‌اش را تغییر می‌دهد، تمامی اشیاء وابسته به آن از آن تغییر مطلع شده و به صورت خودکار به روز می‌شوند. 66 | 67 | - [State](Behavioural/State): به شیء این اجازه را می‌دهد که وقتی وضعیت درونی‌اش تغییر کرد، رفتارش را تغییر دهد. به نظر می‌رسد که شیء کلاس خود را عوض می‌کند. 68 | 69 | - [Strategy](Behavioural/Strategy): خانواده‌ای از الگوریتم ها را تعریف می‌کند، هر یک را کپسوله می‌کند و آن‌ها را جابه‌جا پذیر می‌کند. الگوی استراتژی اجازه می‌دهد که الگوریتم‌ها مستقل از کارخواهی که از آن‌ها استفاده می‌کند، تغییر کنند. 70 | 71 | - [Template Method](Behavioural/TemplateMethod): استخوان‌بندی و شالودهٔ اصلی عملیات الگوریتم را تعریف می‌کند، و پیاده‌سازی هر مرحله را به زیرکلاس‌ها می‌سپارد. این الگو، به زیرکلاس‌ها این اختیار را می‌دهد که تا خودشان، مراحل الگوریتم را پیاده کنند بدون اینکه ساختار الگوریتم را تغییر دهند. 72 | 73 | - [Visitor](Behavioural/Visitor): اعمالی که باید روی عناصری از شیء اجرا شود را ارائه می‌کند. این الگو اجازه را می‌دهد تا اعمال جدیدی تعریف کنید بدون اینکه کلاس‌هایی که این اعمال روی آن‌ها انجام می‌شود را تغییر دهید. 74 | 75 | 76 | 77 | # سپاسگزاری 78 | - با تشکر از [استینلی شیکو](https://github.com/shyiko) که دیاگرام‌های UML را رسم کرده است و اجازهٔ استفاده از آن‌ها در پروژه را به من داد. 79 | - با تشکر از [شیانگ وانگ](http://www.cppblog.com/converse/) که ایدهٔ اصلی مثال‌های سی‌پلاس‌پلاس بخش Classic از اوست، اکثر این مثال‌ها در حقیقت ساده شده و مشتقی از کار شیانگ محسوب می‌شود که اجازهٔ استفاده از آن‌ها را به من داد. 80 | 81 | # معرفی کتاب 82 |
83 | - [Gang Of Four (GoF) : Design Patterns Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Help Ralph Johnson, and John Vlisides.](http://c2.com/cgi/wiki?GangOfFour) 84 | - [Head First Design Patterns by Eric and Elisabeth Freeman.](http://c2.com/cgi/wiki?HeadFirstDesignPatterns) 85 | --------------------------------------------------------------------------------