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 | Decorator - structural design pattern

MetaTrader Experts, Indicators, Scripts and Libraries
//+------------------------------------------------------------------+  //|                                                    Decorator.mqh |  //|                                    2019-2020, dimitri pecheritsa |  //|                                                 792112@gmail.com |  //+------------------------------------------------------------------+  //| decorator < structural design pattern                            |  //+------------------------------------------------------------------+  //   design patterns: elements of reusable object-oriented software  //   gof > erich gamma, richard helm, ralph johnson, john vlissides  //   published in 1994  //+------------------------------------------------------------------+  //| intent                                                           |  //+------------------------------------------------------------------+  //   attach — additional responsibilities — to an object dynamically  //   provide — flexible alternative to subclassing — for extending  //    functionality  //+------------------------------------------------------------------+  //| benefits                                                         |  //+------------------------------------------------------------------+  //   variable aspect > responsibilities of an object without subclassing  //   code refactoring  //      inability to alter classes conveniently > also > adapter, visitor  //      extending functionality by subclassing  //         solution > composition/delegation for combining behavior  //         also > bridge, chain of responsibility, composite,  //          observer, strategy  //+------------------------------------------------------------------+  //| applicability                                                    |  //+------------------------------------------------------------------+  //   add responsibilities — to individual objects —  //      dynamically and transparently — without affecting other objects  //   for responsibilities that can be withdrawn  //   when extension by subclassing is impractical  //      sometimes a large number of independent extensions are possible  //       and would produce an explosion of subclasses to support  //       every combination  //      or a class definition may be hidden  //      or otherwise unavailable for subclassing  //+------------------------------------------------------------------+  //| structure                                                        |  //+------------------------------------------------------------------+  //  //                  | Component |<------------------------------+  //                  |-----------|                               |  //                  |Operation()|                               |  //                        ^                                     |  //                        |                                     |  //            +-----------+-------------+                       |  //            |                         |             component |  //   |ConcreteComponent|    |       Decorator       |-----------+  //   |-----------------|    |-----------------------|  //   |Operation()      |    |Operation()            |  //                          |  component.Operation()|  //                                      ^  //                                      |  //                        +-------------+----------+  //                        |                        |  //               |ConcreteDecoratorA|  |   ConcreteDecoratorB  |  //               |------------------|  |-----------------------|  //               |Operation()       |  |Operation()            |  //               |------------------|  | Decorator::Operation()|  //               |added_state       |  | AddedBehavior()       |  //                                     |AddedBehavior()        |  //  #include <SRC\Patterns\PatternOrganizer.mqh>  namespace Decorator  {  //+------------------------------------------------------------------+  //| participants > component                                         |  //+------------------------------------------------------------------+  class Component  //   defines — interface for objects  //      can have responsibilities added to them dynamically    {  public:     virtual void      Operation(void)=0;    };  //+------------------------------------------------------------------+  //| participants > decorator                                         |  //+------------------------------------------------------------------+  class Decorator:public Component  //   maintains — reference to a component object  //   defines — interface — conforms to component's interface    {  public:     Component*        component;     void              Operation(void);    };  //+------------------------------------------------------------------+  //| participants > decorator                                         |  //+------------------------------------------------------------------+  void Decorator::Operation(void)    {     if(CheckPointer(component)>0)       {        component.Operation();       }    }  //+------------------------------------------------------------------+  //| participants > concrete component                                |  //+------------------------------------------------------------------+  class ConcreteComponent:public Component  //   defines — object — to which additional responsibilities can be attached    {  public:     void              Operation(void);    };  //+------------------------------------------------------------------+  //| participants > concrete component                                |  //+------------------------------------------------------------------+  void ConcreteComponent::Operation(void)    {     Print("concrete operation");    }  //+------------------------------------------------------------------+  //| participants > concrete decorator                                |  //+------------------------------------------------------------------+  //   adds responsibilities to the component  //+------------------------------------------------------------------+  //| participants > concrete decorator > a                            |  //+------------------------------------------------------------------+  class ConcreteDecoratorA:public Decorator    {  protected:     string            added_state;  public:                       ConcreteDecoratorA(void);     void              Operation(void);    };  //+------------------------------------------------------------------+  //| participants > concrete decorator > a                            |  //+------------------------------------------------------------------+  ConcreteDecoratorA::ConcreteDecoratorA(void):     added_state("added state")    {    }  //+------------------------------------------------------------------+  //| participants > concrete decorator > a                            |  //+------------------------------------------------------------------+  void ConcreteDecoratorA::Operation(void)    {     Decorator::Operation();     Print(added_state);    }  //+------------------------------------------------------------------+  //| participants > concrete decorator > b                            |  //+------------------------------------------------------------------+  class ConcreteDecoratorB:public Decorator    {  public:     void              AddedBehavior(void);     void              Operation(void);    };  //+------------------------------------------------------------------+  //| participants > concrete decorator > b                            |  //+------------------------------------------------------------------+  void ConcreteDecoratorB::AddedBehavior(void)    {     Print("added behavior");    }  //+------------------------------------------------------------------+  //| participants > concrete decorator > b                            |  //+------------------------------------------------------------------+  void ConcreteDecoratorB::Operation(void)    {     Decorator::Operation();     AddedBehavior();    }  //+------------------------------------------------------------------+  //| participants > client                                            |  //+------------------------------------------------------------------+  class Client:public ClientExample    {  public:     string            Output(void);     void              Run(void);    };  string Client::Output(void) {return __FUNCTION__;}  //+------------------------------------------------------------------+  //| collaborations                                                   |  //+------------------------------------------------------------------+  void Client::Run(void)  //   decorator  //      forwards — requests — to its component object  //      it may optionally perform — additional operations before and  //       after forwarding the request    {     Component* component=new ConcreteComponent();     Decorator* decorator_a=new ConcreteDecoratorA();     Decorator* decorator_b=new ConcreteDecoratorB();     decorator_a.component=component;     decorator_b.component=decorator_a;     decorator_b.Operation();  //---     delete component;     delete decorator_a;     delete decorator_b;    }  }  //+------------------------------------------------------------------+  //| output                                                           |  //+------------------------------------------------------------------+  //   Decorator::Client::Output  //   concrete operation  //   added state  //   added behavior  //+------------------------------------------------------------------+  //| consequences                                                     |  //+------------------------------------------------------------------+  //   more flexibility than static inheritance  //      responsibilities can be added and removed at run-time  //       simply by attaching and detaching them  //      easy to add a property twice  //   avoids feature-laden classes high up in the hierarchy  //      add functionality incrementally  //         define — new decorators independently  //            from the classes of objects they extend  //            even for unforeseen extensions  //   a decorator and its component aren't identical  //   lots of little objects  //+------------------------------------------------------------------+  //| implementation                                                   |  //+------------------------------------------------------------------+  //   interface conformance > decorator-component  //   omitting the abstract decorator class — if single responsibility  //   keeping components lightweight  //   changing the skin of an object versus changing its guts > strategy  //+------------------------------------------------------------------+  //| related patterns                                                 |  //+------------------------------------------------------------------+  //   adapter > will give an object a completely — new interface  //      decorator > changes object's responsibilities, not its interface  //   composite  //      decorator — is a degenerate composite with only one component —  //       not intended for object aggregation  //   strategy > change the guts of an object  //      decorator > change the skin of an object  //+------------------------------------------------------------------+  
30969