visitor – behavioral design pattern – library MetaTrader 5

//+------------------------------------------------------------------+
//|                                                      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 <MqhPatternsVisitorObjectStructure.mqh>
#include <MqhPatternsVisitorElement.mqh>
#include <MqhPatternsVisitorConcreteElementA.mqh>
#include <MqhPatternsVisitorConcreteElementB.mqh>
#include <MqhPatternsVisitorVisitor.mqh>
#include <MqhPatternsVisitorConcreteVisitor1.mqh>
#include <MqhPatternsVisitorConcreteVisitor2.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.
//
//+------------------------------------------------------------------+
📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks