Expert Advisors • Indicators • Scripts • Libraries

MQL.RobotFX.org is the biggest collection of MetaTrader expert advisors (MT5 & MT4), indicators, scripts and libraries that can be used to improve trading results, minimize risks or simply automate trading tasks

MetaTrader 5 Libraries | Design patterns - Abstract Factory

MetaTrader Experts, Indicators, Scripts and Libraries
//+----------------+----------------------------------------------------------------------------------------+  //|    Abstract    | Provide an interface for creating families of related or dependent objects without     |  //|     Factory    | specifying their concrete classes.                                                     |  //+----------------+----------------------------------------------------------------------------------------+  //|      When      | 1) a system should be independent of how its products are created, composed, and       |  //|                | represented. 2) a system should be configured with one of multiple families of         |  //|                | products. 3) a family of related product objects is designed to be used together, and  |  //|                | you need to enforce this constraint. 4) you want to provide a class library of         |  //|                | products, and you want to reveal just their interfaces, not their implementations.     |  //+----------------+----------------------------------------------------------------------------------------+  //|                                                Structure                                                |  //+---------------------------------------------------------------------------------------------------------+  //  //               +----------------+                                                              +------+  //               | AbstractFactory|<-------------------------------------------------------------|Client|  //               +----------------+                                                              +------+  //               |CreateProductA()|                                +----------------+                |  //               |CreateProductA()|                                |AbstractProductA|<---------------+  //               +----------------+                                +----------------+                |  //                        ^                                                ^                         |  //                        |                                                |                         |  //            +-----------+-----------+                            +-------+------+                  |  //            |                       |                            |              |                  |  //   +----------------+      +----------------+               +---------+    +---------+             |  //   |ConcreteFactory1|- +   |ConcreteFactory2|- - - - + - - >|ProductA2|    |ProductA1|<- - - +     |  //   +----------------+  |   +----------------+        |      +---------+    +---------+       |     |  //   |CreateProductA()|      |CreateProductA()|                                                      |  //   |CreateProductB()|  |   |CreateProductB()|        |                                       |     |  //   +----------------+      +----------------+                                                      |  //                       |                             |                                       |     |  //                                                                 +----------------+                |  //                       |                             |           |AbstractProductB|<---------|-----+  //                                                                 +----------------+  //                       |                             |                   ^                   |  //                                                                         |  //                       |                             |           +-------+------+            |  //                                                                 |              |  //                       |                             |      +---------+    +---------+       |  //                                                     + - - >|ProductB2|    |ProductB1|<- - - +  //                       |                                    +---------+    +---------+       |  //  //                       |                                                                     |  //                       + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +  //  //+-----+----------+----------------------------------------------------------------------------------------+  //| Who | Abstract | declares an interface for operations that create abstract product objects.             |  //|     |  Factory |                                                                                        |  //|     +----------+----------------------------------------------------------------------------------------+  //|     | Concrete | implements the operations to create concrete product objects.                          |  //|     |  Factory |                                                                                        |  //|     +----------+----------------------------------------------------------------------------------------+  //|     | Abstract | declares an interface for a type of product object.                                    |  //|     |  Product |                                                                                        |  //|     +----------+----------------------------------------------------------------------------------------+  //|     | Concrete | 1) defines a product object to be created by the corresponding concrete factory. 2)    |  //|     |  Product | implements the AbstractProduct interface.                                              |  //|     +----------+----------------------------------------------------------------------------------------+  //|     |   Client | uses only interfaces declared by AbstractFactory and AbstractProduct classes.          |  //+-----+----------+----------------------------------------------------------------------------------------+  //|       How      | 1) Normally a single instance of a ConcreteFactory class is created at run-time. This  |  //|                | concrete factory creates product objects having a particular implementation. To        |  //|                | create different product objects, clients should use a different concrete factory. 2)  |  //|                | AbstractFactory defers creation of product objects to its ConcreteFactory subclass.    |  //+----------------+----------------------------------------------------------------------------------------+  //|       Why      | 1) It isolates concrete classes: Clients manipulate instances through their abstract   |  //|                | interfaces. 2) It makes exchanging product families easy: use different product        |  //|                | configurations simply by changing the concrete factory; the whole product family       |  //|                | changes at once. 3) It promotes consistency among products. 4) Supporting new kinds    |  //|                | of products is difficult: requires extending the factory interface, AbstractFactory    |  //|                | class and all of its subclasses.                                                       |  //+----------------+----------------------------------------------------------------------------------------+  //|      Notes     | 1) Factories as singletons. 2) Creating the products: define a factory method for      |  //|                | each product. If many product families are possible, the concrete factory can be a     |  //|                | Prototype: no new concrete factory class for each new product family. 3) Defining      |  //|                | extensible factories: AbstractFactory will only need a single "Make" operation with a  |  //|                | parameter indicating the kind of object to create; all objects have the same abstract  |  //|                | base class.                                                                            |  //+----------------+----------------------------------------------------------------------------------------+  //|                                                   Code                                                  |  //+---------------------------------------------------------------------------------------------------------+  #include <SRC\Patterns\Patterns.mqh>  namespace AbstractFactory  {  interface AbstractProductA {};  interface AbstractProductB {void Interact(AbstractProductA*);};  interface AbstractFactory    {     AbstractProductA* CreateProductA();     AbstractProductB* CreateProductB();    };  //--------------------------------------------------------------------  class ProductA1:public AbstractProductA {public:ProductA1(); ~ProductA1();};  void ProductA1::ProductA1(void) {Print(" Product A1 constructed.");}  void ProductA1::~ProductA1(void) {Print(" Product A1 destructed.");}  //--------------------------------------------------------------------  class ProductA2:public AbstractProductA {public:ProductA2(); ~ProductA2();};  void ProductA2::ProductA2(void) {Print(" Product A2 constructed.");}  void ProductA2::~ProductA2(void) {Print(" Product A2 destructed.");}  //--------------------------------------------------------------------  class ProductB1:public AbstractProductB    {  public:                       ProductB1();                      ~ProductB1();     void              Interact(AbstractProductA*);    };  void ProductB1::ProductB1(void) {Print(" Product B1 constructed.");}  void ProductB1::~ProductB1(void) {Print(" Product B1 destructed.");}  void ProductB1::Interact(AbstractProductA*p) {Print("  Product B1: ",&this," interacts with Product A: ",p);}  //--------------------------------------------------------------------  class ProductB2:public AbstractProductB    {  public:                       ProductB2();                      ~ProductB2();     void              Interact(AbstractProductA*);    };  void ProductB2::ProductB2(void) {Print(" Product B2 constructed.");}  void ProductB2::~ProductB2(void) {Print(" Product B2 destructed.");}  void ProductB2::Interact(AbstractProductA*p) {Print("  Product B2: ",&this," interacts with Product A: ",p);}  //--------------------------------------------------------------------  class Factory1:public AbstractFactory    {  public:                       Factory1();                      ~Factory1();     AbstractProductA* CreateProductA();     AbstractProductB* CreateProductB();    };  //---  void Factory1::Factory1(void) {Print("Factory 1 constructed.");}  void Factory1::~Factory1(void) {Print("Factory 1 destructed.");}  AbstractProductA* Factory1::CreateProductA(void) {return new ProductA1;}  AbstractProductB* Factory1::CreateProductB(void)  {return new ProductB1;}  //--------------------------------------------------------------------  class Factory2:public AbstractFactory    {  public:                       Factory2();                      ~Factory2();     AbstractProductA* CreateProductA();     AbstractProductB* CreateProductB();    };  //---  void Factory2::Factory2(void) {Print("Factory 2 constructed.");}  void Factory2::~Factory2(void) {Print("Factory 2 destructed.");}  AbstractProductA* Factory2::CreateProductA(void) {return new ProductA1;}  AbstractProductB* Factory2::CreateProductB(void) {return new ProductB1;}  //--------------------------------------------------------------------  class FactoryClient    {  public:     void              Run();     void              Switch(AbstractFactory*);                       FactoryClient(AbstractFactory*);                      ~FactoryClient();  protected:     AbstractProductA* apa;     AbstractProductB* apb;     AbstractFactory*  factory;     void              Delete();    };  //---  void FactoryClient::FactoryClient(AbstractFactory* af)   {Switch(af);}  void FactoryClient::~FactoryClient(void)                 {Delete();}  void FactoryClient::Run(void)                            {apb.Interact(apa);}  void FactoryClient::Delete(void)    {delete apa; delete apb; delete factory;}  void FactoryClient::Switch(AbstractFactory *af)    {     Delete();     factory=af;     apa=factory.CreateProductA();     apb=factory.CreateProductB();    }  //--------------------------------------------------------------------  class Client:public ClientExample {public:string Output(); void Run();};  string Client::Output(void) {return __FUNCTION__;}  void Client::Run()    {     FactoryClient client(new Factory1);     client.Run();     client.Switch(new Factory2);     client.Run();    }  }  //+---------------------------------------------------------------------------------------------------------+  //|                                                  Output                                                 |  //+---------------------------------------------------------------------------------------------------------+  //Creational::AbstractFactory::Client::Output  //Factory 1 constructed.  // Product A1 constructed.  // Product B1 constructed.  //  Product B1: 126877696 interacts with Product A: 125829120  //Factory 2 constructed.  // Product A1 destructed.  // Product B1 destructed.  //Factory 1 destructed.  // Product A2 constructed.  // Product B2 constructed.  //  Product B2: 130023424 interacts with Product A: 128974848  // Product A2 destructed.  // Product B2 destructed.  //Factory 2 destructed.  
29978