//+------------------------------------------------------------------+ //| PatternOrganizer.mqh | //| 2019-2020, dimitri pecheritsa | //| 792112@gmail.com | //+------------------------------------------------------------------+ //| 23 design patterns | //+------------------------------------------------------------------+ // design patterns: elements of reusable object-oriented software // gof > erich gamma, richard helm, ralph johnson, john vlissides // published in 1994 //+------------------------------------------------------------------+ //| classification | //+------------------------------------------------------------------+ // purpose > creational > 5 // abstract factory, builder, factory method, prototype, singleton // purpose > structural > 7 // adapter, bridge, composite, decorator, facade, flyweight, proxy // purpose > behavioral > 11 // chain of responsibility, command, interpreter, iterator, mediator // memento, observer, state, strategy, template method, visitor // scope > class > 3 > factory method, interpreter, template method // scope > object > 20 > all other //+------------------------------------------------------------------+ //| relationships | //+------------------------------------------------------------------+ // // +-------------->|memento| |proxy| // | ^ |adapter| // saving state | |bridge | // of iteration avoiding // | hysteresis // |builder| |iterator|<---+ | | chain of | // ^ ^ | |command| |responsibility| // | | | | | // creating enumerating | composed defining // composites children | using the chain // | | | | | // +---------|composite|<---|---------+---------------+ // | | | | // adding | defining------------+ defining // responsibilities | traversals | grammar // to objects | | | // | +--------adding------>|visitor| | // v | operations | // |decorator| sharing | | // ^ composites +--------|interpreter|---+ // | | | // | v sharing | // changing skin |flyweight|<-----terminal----+ // vs. guts ^ symbols |observer| // | sharing | | // | strategies---+---sharing | // v | states complex // |strategy|------+ | |mediator|<----dependency // ^ |state| management // | // sharing // algorithm's----------|template method|----often uses---+ // steps | // | // |prototype|<--+ | // | v // configure factory implement---->|factory method| // dynamically using // | | // |abstract factory|---+---------+ // | // single // |singleton|<-----------instance------------|facade| // //+------------------------------------------------------------------+ //| code refactoring | //+------------------------------------------------------------------+ // create objects < explicitly > create indirectly // abstract factory, factory method, prototype // dependence > specific operations > avoid > hard-coded requests // chain of responsibility, command // dependence > hardware and software > limit // abstract factory, bridge // dependence > object representations/implementations // hide from clients > keep changes from cascading // abstract factory, bridge, memento, proxy // algorithmic dependencies > isolate > algorithms that may change // builder, iterator, strategy, template method, visitor // tight coupling > decouple < abstract coupling and layering // abstract factory, bridge, chain of responsibility, // command, facade, mediator, observer // extending functionality < subclassing // composition/delegation > combine behavior // bridge, chain of responsibility, composite, decorator, // observer, strategy // inability to alter classes conveniently > adapter, decorator, visitor //+------------------------------------------------------------------+ //| creational > abstract factory | //+------------------------------------------------------------------+ // interface > families of related/dependent objects // without specifying concrete classes // variable aspect > families of product objects // // | AbstractFactory|<-----------------------------------------|Client| // |----------------| | // |CreateProductA()| | // |CreateProductA()| |AbstractProductA|<-------+ // ^ ^ | // | | | // +-----------+----------+ +-----+-----+ | // | | | | | //|ConcreteFactory1|- + |ConcreteFactory2|- + ->|ProductA2| |ProductA1|<- + | //|----------------| | |----------------| | | | //|CreateProductA()| |CreateProductA()| | //|CreateProductB()| | |CreateProductB()| | | | // |AbstractProductB|<----+--+ // | | ^ | // | // | | +-----+-----+ | // | | // | + ->|ProductB2| |ProductB1|<- + // | // + - - - - - - - - - - - - - - - - - - - - - - - - - + // //+------------------------------------------------------------------+ //| creational > builder | //+------------------------------------------------------------------+ // for a complex object > separate construction from representation // same construction process can create different representations // variable aspect > the way a composite object gets created // // builder // | Director |o--------->| Builder | // |-----------------------------| |-----------| // |Construct() | |BuildPart()| // | for all objects in structure| ^ // | builder.BuildPart() | | // |ConcreteBuilder|- - ->|Product| // |---------------| // |BuildPart() | // |GetResult() | // //+------------------------------------------------------------------+ //| creational > factory method | //+------------------------------------------------------------------+ // interface for creating an object > defers instantiation to subclasses // subclasses decide which class to instantiate // variable aspect > subclass of object that is instantiated // // | Creator | // |------------------------| // |FactoryMethod() | // |AnOperation() | // | ... | // | product=FactoryMethod()| // |Product| | ... | // ^ ^ // | | // |ConcreteProduct|<- - - - -| ConcreteCreator | // |---------------------------| // |FactoryMethod() | // | return new ConcreteProduct| // //+------------------------------------------------------------------+ //| creational > prototype | //+------------------------------------------------------------------+ // create objects > by copying a prototype // variable aspect > class of object that is instantiated // // prototype // | Client |------------>|Prototype| // |--------------------| |---------| // |Operation() | |Clone() | // | p=prototype.Clone()| ^ // | // +-----------+------------+ // | | // | ConcretePrototype1 | | ConcretePrototype2 | // |--------------------| |--------------------| // |Clone() | |Clone() | // | return copy of self| | return copy of self| // //+------------------------------------------------------------------+ //| creational > singleton | //+------------------------------------------------------------------+ // ensure > one instance of a class with a global point of access // variable aspect > the sole instance of a class // // | Singleton | // |----------------------| // |static Instance() | // | return uniqueInstance| // |SingletonOperation() | // |GetSingletonData() | // |----------------------| // |static uniqueInstance | // |singletonData | // //+------------------------------------------------------------------+ //| interface for patterns | //+------------------------------------------------------------------+ interface ClientExample //pattern client { string Output(void); //returns header void Run(void); //execute the pattern client }; //+------------------------------------------------------------------+ //| interface for patterns | //+------------------------------------------------------------------+ void Run(ClientExample* client) //launches a pattern { printf("---n%s",client.Output()); //print pattern header client.Run(); //execute client collaborations delete client; //exit } //+------------------------------------------------------------------+ //| include > patterns | //+------------------------------------------------------------------+ namespace Creational { #include "CreationalAbstractFactory.mqh" #include "CreationalBuilder.mqh" #include "CreationalFactoryMethod.mqh" #include "CreationalPrototype.mqh" #include "CreationalSingleton.mqh" } //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //| Pattern.mq5 | //| 2019-2020, dimitri pecheritsa | //| 792112@gmail.com | //+------------------------------------------------------------------+ #include <SRCPatternsPatternOrganizer.mqh> //+------------------------------------------------------------------+ //| run | //+------------------------------------------------------------------+ void OnStart() //launch pattern clients one by one and check result { //---creational Run(new Creational::AbstractFactory::Client); Run(new Creational::Builder::Client); Run(new Creational::FactoryMethod::Client); Run(new Creational::Prototype::Client); Run(new Creational::Singleton::Client); } //+------------------------------------------------------------------+ //| output > abstract factory | //+------------------------------------------------------------------+ // Creational::AbstractFactory::Client::Output // client is requesting to create factory 1 // client is requesting to create the factory client // client is requesting the factory client to manage factory 1 // factory 1: 3145728 constructed // factory client created and received abstract factory 3145728 // factory client is requesting to accept/switch the factories // factory client is accepting new factory 3145728 // factory client saved the new factory // factory client is requesting its new factory to create product a // factory 1 is creating and returning product a1 // product a1 constructed // factory client is requesting its new factory to create product b // factory 1 is creating and returning product b1 // product b1 constructed // client is requesting the factory client to operate // factory client is running abstract product b // product b1: 5242880 is interacting with product a: 4194304 // client is requesting to create new factory 2 and asking factory client to switch factories // factory 2: 6291456 constructed // factory client is switching old factory 3145728 to new factory 6291456 // factory client saved the new factory // factory client is requesting its new factory to create product a // factory 2 is creating and returning product a2 // product a2 constructed // factory client is requesting its new factory to create product b // factory 2 is creating and returning product b2 // product b2 constructed // client is requesting the factory client to run again // factory client is running abstract product b // product b2: 8388608 is interacting with product a: 7340032 //+------------------------------------------------------------------+ //| output > builder | //+------------------------------------------------------------------+ // Creational::Builder::Client::Output // client is requesting to create a new concrete builder // client is requesting to create a director and give him the builder // director created and received builder 10485760 // client is requesting the director to perform the construction // director has started the construction // director is requesting its builder to build the product parts // builder is requesting the product to add part a to itself // product added part a to itself // builder has made part a and added it to the product // builder is requesting the product to add part b to itself // product added part b to itself // builder has made part b and added it to the product // builder is requesting the product to add part c to itself // product added part c to itself // builder has made part c and added it to the product // director's builder constructed the product from parts // client is requesting the builder to return the result product // builder is returning the product // client is requesting the product the describe itself // product is showing all parts that it is made of // part a // part b // part c //+------------------------------------------------------------------+ //| output > factory method | //+------------------------------------------------------------------+ // Creational::FactoryMethod::Client::Output // requesting to make a creator // requesting creator to run its factory method to return the product // creator is running a factory method // concrete creator is creating and returning new concrete product // concrete product: 15728640 created // requesting creator to run its operation // creator is running its operation // creator is running a factory method // concrete creator is creating and returning new concrete product // concrete product: 16777216 created // creator has saved the product received from a virtual factory method //+------------------------------------------------------------------+ //| output > prototype | //+------------------------------------------------------------------+ // Creational::Prototype::Client::Output // requesting to create a concrete prototype 1 with id 1 // prototype 18874368, id: 1 created // concrete prototype 1: 18874368, id: 1 created // requesting prototype 18874368 to create its clone // cloning concrete prototype 1: 18874368, id: 1 // prototype 19922944, id: 1 created // concrete prototype 1: 19922944, id: 1 created // requesting to create a concrete prototype 2 with id 2 // prototype 20971520, id: 2 created // concrete prototype 2: 20971520, id: 2 created // requesting prototype 20971520 to create its clone // cloning concrete prototype 2: 20971520, id: 2 // prototype 22020096, id: 2 created // concrete prototype 2: 22020096, id: 2 created //+------------------------------------------------------------------+ //| output > singleton | //+------------------------------------------------------------------+ // Creational::Singleton::Client::Output // requesting singleton instance 1 // singleton instance method is running // unique instance of the singleton is empty // singleton 24117248 created // singleton assigned to unique instance // unique instance contains singleton: 24117248 // returning the unique instance 24117248 of the singleton // requesting singleton instance 2 // singleton instance method is running // unique instance contains singleton: 24117248 // returning the unique instance 24117248 of the singleton // instances 1 and instance 2 are same objects // requesting singleton operation on instance 1 // running singleton operation > setting singleton data // requesting singleton data via singleton instance 2 // reading and returning singleton data // singleton data //+------------------------------------------------------------------+