//+------------------------------------------------------------------+
//| 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 <SRC\Patterns\PatternOrganizer.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
//+------------------------------------------------------------------+
#30801LibrariesMetaTrader 5👁 3459 views
Bridge - structural design pattern
D
Author
DMITRII PECHERITSAPublished date
Aug 27, 2020
📚Related Articles
← View other articles →#77531Libraries
CSetupLedger: a per-setup win rate ledger for Expert Advisors
Why I wrote it My scalper trades two setups. A bullish order block and the bearish mirror of it. The Strategy Tester gave me one profit factor for both of them. I spent two weeks t...
Ali AkbarView detail →
#77488Libraries
Position sizing from risk, using the broker's own tick value and volume step
Every lot size calculator that assumes one pip is worth ten dollars is wrong on gold, wrong on indices, wrong on JPY crosses and wrong on any account not denominated in USD which i...
Ralph Ivan SimeonView detail →
#77156Libraries
PropFirm Defense
A prop firm account runs under a second rulebook MetaTrader 5 knows nothing about: a maximum loss measured from a fixed starting balance, a daily limit that resets at an hour the b...
Bruno Nunes Myrrha RibeiroView detail →