Bridge – structural design pattern – library MetaTrader 5

//+------------------------------------------------------------------+
//|                                                       Bridge.mqh |
//|                                     2019-2020, dmitri pecheritsa |
//|                                                 792112@gmail.com |
//+------------------------------------------------------------------+
//| bridge > structural design pattern                               |
//+------------------------------------------------------------------+
//   design patterns: elements of reusable object-oriented software
//   gof > erich gamma, richard helm, ralph johnson, john vlissides 
//   published in 1994
//+------------------------------------------------------------------+
//| intent                                                           |
//+------------------------------------------------------------------+
//   abstraction and implementation > decoupled, vary independently
//+------------------------------------------------------------------+
//| benefits                                                         |
//+------------------------------------------------------------------+
//   variable aspect > implementation of an object
//   refactoring problems
//      dependence on hardware and software platform
//      dependence on object representations/implementations
//      tight coupling
//      extending functionality by subclassing
//   refactoring solutions
//      limit platform dependencies
//         also > abstract factory, bridge
//      hide the dependence from clients to keep changes from cascading
//         also > abstract factory, bridge, memento, proxy
//      decouple with abstract coupling and layering
//         also
//            abstract factory, bridge, chain of responsibility,
//            command, facade, mediator, observer
//      composition/delegation
//         more flexible than inheritance for combining behavior
//         also
//            bridge, chain of responsibility, composite, decorator,
//            observer, strategy
//+------------------------------------------------------------------+
//| applicability                                                    |
//+------------------------------------------------------------------+
//   abstraction/implementation
//      not bound > switch implementation at run-time
//      extensible by subclassing > combine/extend independently
//   implementation of an abstraction
//      change has no impact on clients (no recompilation)
//      can be hidden from clients in c++
//   proliferation of classes > split object into two parts
//   implementation can be shared among multiple objects (reference counting)
//+------------------------------------------------------------------+
//| structure                                                        |
//+------------------------------------------------------------------+
//
//|Client|
//   |
//   +-->|   Abstraction  |----------------->| Implementor  |
//       |----------------|                  |--------------|
//       |Operation()     |                  |OperationImp()|
//       | imp.Operation()|                         ^
//               ^                                  |
//               |                       +----------+----------+
//               |                       |                     |
//      |RefinedAbstraction|  |ConcreteImplementorA| |ConcreteImplementorB|
//                            |--------------------| |--------------------|
//                            |OperationImp()      | |OperationImp()      |
//
#include <SRCPatternsPatternOrganizer.mqh>
namespace Bridge
{
//+------------------------------------------------------------------+
//| participants                                                     |
//+------------------------------------------------------------------+
interface Implementor
//   defines the interface for implementation classes
//   implementor interface provides only primitive operations
//   abstraction defines higher-level operations based on these primitives
  {
   void OperationImp(void);
  };
//+------------------------------------------------------------------+
//| participants                                                     |
//+------------------------------------------------------------------+
class Abstraction
//   defines the abstraction's interface
//   maintains a reference to an object of type implementor
  {
public:
   virtual void      Operation(void);
                     Abstraction(Implementor*);
                     Abstraction(void);
                    ~Abstraction(void);
protected:
   Implementor*      implementor;
  };
void Abstraction::Abstraction(void) {}
//+------------------------------------------------------------------+
//| participants > abstraction                                       |
//+------------------------------------------------------------------+
void Abstraction::Abstraction(Implementor*i):implementor(i)
  {
   Print("abstracton created with implementor ",i);
   Print("implementor ",i," saved by abstraction");
  }
//+------------------------------------------------------------------+
//| participants > abstraction                                       |
//+------------------------------------------------------------------+
void Abstraction::~Abstraction(void)
  {
   delete implementor;
  }
//+------------------------------------------------------------------+
//| participants > abstraction                                       |
//+------------------------------------------------------------------+
void Abstraction::Operation(void)
  {
   Print("abstraction is requesting in own operation its implementor ",
         implementor," to run its operation in turn");
   implementor.OperationImp();
  }
//+------------------------------------------------------------------+
//| participants                                                     |
//+------------------------------------------------------------------+
class RefinedAbstraction:public Abstraction
//   extends the interface defined by abstraction
  {
public:
                     RefinedAbstraction(Implementor*);
   void              Operation(void);
  };
//+------------------------------------------------------------------+
//| participants > refined abstraction                               |
//+------------------------------------------------------------------+
void RefinedAbstraction::RefinedAbstraction(Implementor*i):Abstraction(i)
  {
   Print("refined abstraction created, received implementor ",i,
         " via the abstracton constructor");
  }
//+------------------------------------------------------------------+
//| participants > refined abstraction                               |
//+------------------------------------------------------------------+
void RefinedAbstraction::Operation(void)
  {
   Print("refined abstraction operation is running");
   Print("refined abstraction ",&this," is requesting its parent's abstraction operation");
   Abstraction::Operation(); //...
  }
//+------------------------------------------------------------------+
//| participants                                                     |
//+------------------------------------------------------------------+
//   concrete implementor                              
//      implements the implementor interface
//      defines its concrete implementation
//+------------------------------------------------------------------+
//| participants > concrete implementor                              |
//+------------------------------------------------------------------+
class ConcreteImplementorA:public Implementor
  {
public:
   void              OperationImp(void);
  };
void ConcreteImplementorA::OperationImp(void)
  {
   Print("concrete implementor a ",&this," is running operation");
  }
//+------------------------------------------------------------------+
//| participants > concrete implementor                              |
//+------------------------------------------------------------------+
class ConcreteImplementorB:public Implementor
  {
public:
   void              OperationImp(void);
  };
void ConcreteImplementorB::OperationImp(void)
  {
   Print("concrete implementor b ",&this," is running operation");
  }
//+------------------------------------------------------------------+
//| participants                                                     |
//+------------------------------------------------------------------+
class Client:public ClientExample
  {
public:
   string            Output(void);
   void              Run(void);
  };
string Client::Output(void) {return __FUNCTION__;}
//+------------------------------------------------------------------+
//| collaborations                                                   |
//+------------------------------------------------------------------+
void Client::Run(void)
//   abstraction forwards client requests to its implementor object
  {
   Abstraction* abstraction;
//---
   Print("creating refined abstraction with concrete implementor a");
   abstraction=new RefinedAbstraction(new ConcreteImplementorA);
   Print("requesting abstraction operation");
   abstraction.Operation();
   delete abstraction;
//---
   Print("creating refined abstraction with concrete implementor b");
   abstraction=new RefinedAbstraction(new ConcreteImplementorB);
   Print("requesting abstraction operation");
   abstraction.Operation();
   delete abstraction;
  }
}
//+------------------------------------------------------------------+
//| output                                                           |
//+------------------------------------------------------------------+
//   Structural::Bridge::Client::Output
//   creating refined abstraction with concrete implementor a
//   abstracton created with implementor 34603008
//   implementor 34603008 saved by abstraction
//   refined abstraction created, received implementor 34603008 via the abstracton constructor
//   requesting abstraction operation
//   refined abstraction operation is running
//   refined abstraction 33554432 is requesting its parent's abstraction operation
//   abstraction is requesting in own operation its implementor 34603008 to run its operation in turn
//   concrete implementor a 34603008 is running operation
//   creating refined abstraction with concrete implementor b
//   abstracton created with implementor 36700160
//   implementor 36700160 saved by abstraction
//   refined abstraction created, received implementor 36700160 via the abstracton constructor
//   requesting abstraction operation
//   refined abstraction operation is running
//   refined abstraction 35651584 is requesting its parent's abstraction operation
//   abstraction is requesting in own operation its implementor 36700160 to run its operation in turn
//   concrete implementor b 36700160 is running operation
//+------------------------------------------------------------------+
//| consequences                                                     |
//+------------------------------------------------------------------+
//   decoupling interface and implementation
//      can be configured at run-time
//      no compile-time dependencies/recompilation
//      encourages layering > better-structured system
//         high-level part of a system > knows abstraction and implementor
//   improved extensibility > abstraction and implementor are independent
//   hiding implementation details from clients
//+------------------------------------------------------------------+
//| implementation                                                   |
//+------------------------------------------------------------------+
//   only one implementor
//   creating the right implementor object
//      if abstraction knows all concrete implementors
//         instantiate one of them in its constructor
//         decide between them based on parameters passed to its constructor
//      default implementation
//         choose initially
//         change later according to usage
//      delegate the decision to another object (factory) altogether
//   sharing implementors > handle/body idiom
//   multiple inheritance
//      publicly from abstraction
//      privately from a concrete implementor
//      binds an implementation permanently to its interface
//+------------------------------------------------------------------+
//| related patterns                                                 |
//+------------------------------------------------------------------+
//   abstract factory > create and configure a particular bridge
//   adapter
//      geared toward making unrelated classes work together
//      applied to systems after they're designed
//      bridge > used up-front in a design
//+------------------------------------------------------------------+
📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks