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 | visitor - behavioral design pattern

MetaTrader Experts, Indicators, Scripts and Libraries
//+------------------------------------------------------------------+  //|                                                      Visitor.mq5 |  //|                                    2019-2020, dimitri pecheritsa |  //|                                                 792112@gmail.com |  //+------------------------------------------------------------------+  //  //   visitor - behavioral design pattern  //  //   from: design patterns: elements of reusable object-oriented software  //   by gof: erich gamma, richard helm, ralph johnson, john vlissides  //   published in 1994  //  //   intent  //     //   represent an operation to be performed on the elements of an object   //structure. visitor lets you define a new operation without changing   //the classes of the elements on which it operates.  //  //   applicability  //  //   use the visitor pattern when  //      an object structure contains many classes of objects with differing   //interfaces, and you want to perform operations on these objects that   //depend on their concrete classes.  //      many distinct and unrelated operations need to be performed on   //objects in an object structure, and you want to avoid "polluting" their   //classes with these operations. visitor lets you keep related operations   //together by defining them in one class. when the object structure is   //shared by many applications, use visitor to put operations in just those   //applications that need them.  //      the classes defining the object structure rarely change, but you   //often want to define new operations over the structure. changing the   //object structure classes requires redefining the interface to all visitors,   //which is potentially costly. if the object structure classes change   //often, then it's probably better to define the operations in those classes.  //  //   structure  //  //|Client|---------->|                Visitor                |  //   |               |---------------------------------------|  //   |               |VisitConcreteElementA(ConcreteElementA)|  //   |               |VisitConcreteElementB(ConcreteElementB)|  //   |                                  ^  //   |                                  |  //   |                  +---------------+---------------+  //   |                  |                               |  //   |       |   ConcreteVisitor1    |     |    ConcreteVisitor2   |  //   |       |---------------------- |     |-----------------------|  //   |       |VisitConcreteElementA( |     |VisitConcreteElementA( |  //   |       | ConcreteElementA)     |     | ConcreteElementA)     |  //   |       |VisitConcreteElementB( |     |VisitConcreteElementB( |  //   |       | ConcreteElementB)     |     | ConcreteElementB)     |  //   |  //   |  //   +--->|ObjectStructure|--->*|    Element    |  //                              |---------------|  //                              |Accept(Visitor)|  //                                      ^  //                                      |  //                   +------------------+------------------+  //                   |                                     |  //    |       ConcreteElementA       |     |       ConcreteElementB       |  //    |------------------------------|     |------------------------------|  //    |Accept(Visitor)               |     |Accept(Visitor)               |  //    | v.VisitConcreteElementA(this)|     | v.VisitConcreteElementB(this)|  //    |OperationA()                  |     |OperationB()                  |  //  //  //   participants  //  //   visitor   //      declares a visit operation for each class of concrete element   //in the object structure. the operation's name and signature identifies   //the class that sends the visit request to the visitor. that lets the   //visitor determine the concrete class of the element being visited. then   //the visitor can access the element directly through its particular interface.  //   concrete visitor   //      implements each operation declared by visitor. each operation   //implements a fragment of the algorithm defined for the corresponding   //class of object in the structure. concrete visitor provides the context   //for the algorithm and stores its local state. this state often accumulates   //results during the traversal of the structure.  //   element   //      defines an accept operation that takes a visitor as an argument.  //   concrete element   //      implements an accept operation that takes a visitor as an argument.  //   object structure   //      can enumerate its elements.  //      may provide a high-level interface to allow the visitor to visit   //its elements.  //      may either be a composite or a collection such as a list or a set.  //  //   collaborations  //  //   a client that uses the visitor pattern must create a concrete visitor   //object and then traverse the object structure, visiting each element   //with the visitor.  //   when an element is visited, it calls the visitor operation that corresponds   //to its class. the element supplies itself as an argument to this operation   //to let the visitor access its state, if necessary.  //   the following interaction diagram illustrates the collaborations   //between an object structure, a visitor, and two elements:  //     //   anObject        aConcreteElementA   aConcreteElementB      aConcreteVisitor  //   Structure              |                   |                      |  //      |                   |                   |                      |  //     | |Accept(aVisitor)  |                   |                      |  //     | |---------------->| |VisitConcreteElementA(aConcreteElementA) |   //     | |                 | |------------------|-------------------->| |  //     | |                  |                   |                     | |  //     | |                 | |<-----------------|---------------------| |  //     | |Accept(aVisitor)  |                   |                      |  //     | |------------------|----------------->| |VisitConcrete        |   //     | |                  |                  | | ElementB(aConcrete | |  //     | |                  |                  | | ElementB)          | |  //     | |                  |                  | |------------------->| |  //     | |                  |                   |                     | |  //     | |                  |                  | |<-------------------| |  //      |                   |                   |                      |  //  //+------------------------------------------------------------------+  //|                                              example of a client |  //+------------------------------------------------------------------+  #include <Mqh\Patterns\Visitor\ObjectStructure.mqh>  #include <Mqh\Patterns\Visitor\Element.mqh>  #include <Mqh\Patterns\Visitor\ConcreteElementA.mqh>  #include <Mqh\Patterns\Visitor\ConcreteElementB.mqh>  #include <Mqh\Patterns\Visitor\Visitor.mqh>  #include <Mqh\Patterns\Visitor\ConcreteVisitor1.mqh>  #include <Mqh\Patterns\Visitor\ConcreteVisitor2.mqh>  void OnStart()    {     ObjectStructure structure;     structure.Add(new ConcreteElementA());     structure.Add(new ConcreteElementB());     structure.Accept(new ConcreteVisitor1());     structure.Accept(new ConcreteVisitor2());    }  //   output  //  //   element 2097152 added to the object structure  //   element 3145728 added to the object structure  //     //   object structure has accepted new visitor 4194304  //   object structure has 2 elements  //   object structure is requesting each element to accept the visitor  //   element a has accepted the visitor  //   the element made operation a  //   element b has accepted the visitor  //   the element made operation b  //  //   object structure has accepted new visitor 5242880  //   object structure has 2 elements  //   object structure is requesting each element to accept the visitor  //   element a has accepted the visitor  //   the element made operation a  //   element b has accepted the visitor  //   the element made operation b  //     //  //   consequences  //  //   some of the benefits and liabilities of the visitor pattern are as   //follows:  //      visitor makes adding new operations easy  //      a visitor gathers related operations and separates unrelated ones  //      adding new concrete element classes is hard  //      visiting across class hierarchies  //      accumulating state  //      breaking encapsulation  //  //   implementation  //  //   each object structure will have an associated visitor class. this   //abstract visitor class declares a visit concrete element operation for   //each class of concrete element defining the object structure. each visit   //operation on the visitor declares its argument to be a particular concrete   //element, allowing the visitor to access the interface of the concrete   //element directly. concrete visitor classes override each visit operation   //to implement visitor-specific behavior for the corresponding concrete   //element class.  //   here are two other implementation issues that arise when you apply   //the visitor pattern:  //      double dispatch  //      who is responsible for traversing the object structure?   //  //   related patterns  //  //   composite: visitors can be used to apply an operation over an object   //structure defined by the composite pattern.  //   interpreter: visitor may be applied to do the interpretation.  //  //+------------------------------------------------------------------+  
32433