//+------------------------------------------------------------------+
//| 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 "Creational\AbstractFactory.mqh"
#include "Creational\Builder.mqh"
#include "Creational\FactoryMethod.mqh"
#include "Creational\Prototype.mqh"
#include "Creational\Singleton.mqh"
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Pattern.mq5 |
//| 2019-2020, dimitri pecheritsa |
//| 792112@gmail.com |
//+------------------------------------------------------------------+
#include <SRC\Patterns\PatternOrganizer.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
//+------------------------------------------------------------------+