Welcome Forex EA downloads & MT4/MT5 auto-trading resources — EAs, Gold EAs, quant tools and real-world automation.
Sign In Sign Up

Bridge - Structural Design Pattern - MetaTrader 5 Library | MT5 EA Download - MetaTrader 5 Resources

author EAcpu | 3 reads | 0 comments |
//+------------------------------------------------------------------+
//| bridge.mqh |
//| 2019-2020, Dmitry Pecherica|
//| 792112@gmail.com |
//+------------------------------------------------------------------+
//|Bridge> Structural Design Pattern |
//+------------------------------------------------------------------+
// Design patterns: elements of reusable object-oriented software
// gof > Erich Gamma, Richard Helm, Ralph Johnson, John Freesides
// Published in 1994
//+------------------------------------------------------------------+
//|Intent |
//+------------------------------------------------------------------+
// Abstraction and implementation > Decoupling, independent changes
//+------------------------------------------------------------------+
//|Benefits|
//+------------------------------------------------------------------+
// Variable aspect > Object implementation
// Refactor the problem
// Dependence on hardware and software platforms
// Dependence on object representation/implementation
// tight coupling
// Extend functionality through subclassing
//Refactor solution
// Limit platform dependencies
// also> abstract factory, bridge
//Hide client dependencies to prevent cascading changes
// also > abstract factory, bridge, memo, proxy
// Decoupling through abstract coupling and layering
// return
//Abstract factory, bridge, responsibility chain,
//command, appearance, mediator, observer
// Combination/Delegation
// Composition behavior is more flexible than inheritance
// return
// bridge, chain of responsibility, composite, decorator,
// Observer, strategy
//+------------------------------------------------------------------+
//|Applicability |
//+------------------------------------------------------------------+
// abstract/implementation
// Unbound > Switch implementation at runtime
// Extensible via subclassing > independent composition/extension
//Abstract implementation
// Changes have no impact on the client (no need to recompile)
// Can be hidden from clients in C++
//Proliferation of classes> Split the object into two parts
// Implementation can be shared between multiple objects (reference counting)
//+------------------------------------------------------------------+
//|Structure |
//+------------------------------------------------------------------+
//
//|Client|
// |
// +-->| Abstract |------------------>|Implementer|
// |----------------| |----------------|
// |Operation()| |OperationImp()|
// | imp.Operation()| ^
// ^ |
// | +----------+----------+
// | | |
// |Exquisite abstraction| |Concrete implementer A| |Concrete implementer B|
// |--------------------| |--------------------|
// |OperationImp() | |OperationImp() |
//an> #include Namespace Bridge { //+------------------------------------------------------------------+ //| Actor | //+------------------------------------------------------------------+ Interface Implementer // Define the interface of the implementation class // Implementer interface only provides primitive operations // Abstraction defines higher-level operations based on these primitives { Blank Operation Imp( blank ); }; //+------------------------------------------------------------------+ //| Actor | //+------------------------------------------------------------------+ Class Abstract // Define the abstract interface // Maintain a reference to an object of type implementer { public : virtual void operation( void ); abstract(implementer*); abstract( void ); ~Abstract( void ); protected : implementer* implementer; }; void abstract::abstract( void ){} //+-------------------------------------------------------------------------------- + //|actor>abstract | //+----------------------------------------------------------------+ void abstract::abstract(implementer*i): implementor(i) { print ( "Abstract created by implementer" , i); print ( "Implementer" , i, "saved by abstraction" ); } //+ ------------------------------------------------------------------ + //| Actor>Abstract | // + ------------------------------------------------------------------+ Blank Abstract::~Abstract( blank ) { Remove implementer; } //+------------------------------------------------------------------+ //| Actor> Abstract | //+-----------------------------------------------------------------+ Blank Abstract:::Operation( blank ) { Print ( "An abstraction is asking its implementers in their own operations " , implementers, "to run their operations in turn" ) ; implementer.OperationImp (); } //+------------------------------------------------------------------+ //|Participant | //+------------------------------------------------------------------+ //|Participant> RefinedAbstraction | //+------------------------------------------------------------------+ Blank RefinedAbstraction::RefinedAbstraction(Implementor*i):Abstraction(i) { print ( "Created RefinedAbstraction, receiving the implementor , i, "through the abstract constructor" ); } //+------------------------------------------------------------------+ //| Actor > RefinedAbstraction | //+------------------------------------------------------------------+ Blank RefinedAbstraction::Operation( Blank ) { print ( "Refined Abstract Exercises"The operation is running"); print ( "Refined Abstraction" ,& this , "Requesting the abstract operation of its parent" ); Abstract::Operation(); //... } //+------------------------------------------------------------------+ //|Participant | //+------------------------------------------------------------------+ // Concrete implementer // Implement the implementer interface // Define its concrete implementation //+----------------------------------------------------------------+ //|Participant > Concrete Implementer | //+------------------------------------------------------------------+ Class Concrete Implementer A: People Implementer { People : Blank Operation Imp( blank ); }; Blank Concrete Implementer A::OperationImp( blank ) { Print (" Concrete Implementer a" ,& this , "Running Operation" ); } // +------------------------------------------------------------------+ // |Participant > Concrete Implementer | //+----------------------------------------------------------------+ Class Concrete Implementer B: People Implementer { People : Blank Operation Imp( blank ); }; void concrete implementer B::OperationImp( blank ) { print (" concrete implementer B" , & this , " running operation" ) ; } //+------------------------------------------------------------------+ //| participant | // + ------------------------------------------------------------------+ //|participant| //+------------------------------------------------------------------+ //| cooperation | //+------------------------------------------------------------------+ Blank Client::Run( Blank ) // The abstraction forwards client requests to its implementer object { abstract * abstract; //--- print ( "Create refined abstraction with concrete implementer B" ); abstract = new refined abstraction( new concrete implementer A) ; print ( "Request abstract operation" ); abstract = new refined abstraction( new concrete implementer B); print ( "Request abstract operation" ); abstract.Operation(); remove abstraction; } } //+------------------------------------------------------------------+ //|output | //+------------------------------------------------------------------+ // struct::bridge::client::output // Create a refined abstraction using a concrete implementer // Create an abstraction using implementer 34603008 // Implementer 34603008 Saved by abstraction // Create refined abstraction, receive implementer 34603008 through abstract constructor// Request abstract operation // Refined abstract operation is running // Refined abstraction 33554432 is requesting the abstract operation of its parent // The abstraction requests its implementer 34603008 in its own operation to run its operations in turn // Concrete implementer a 34603008 is running the operation // Use concrete implementer b to create refined abstraction // Use abstraction created by implementer 36700160 // Implementer 36700160 Saved by abstraction // Creates refined abstraction, receives implementer 36700160 via abstract constructor // Requests abstract operation // Refined abstract operation is running // Refined abstraction 35651584 is requesting its parent's abstract operation // The abstraction requests its implementer 36700160 in its own operation, which in turn runs its operations // Concrete implementor b 36700160 Running operation //+------------------------------------------------------------------+ //|Consequences | //+------------------------------------------------------------------+ // Interface and implementation decoupled // Can be configured at runtime // No compile-time dependencies/recompilation // Encourage layering > Better structured system // High-level parts of the system > Understand abstractions and implementers // Improved scalability > Abstraction and implementation are independent // Hide implementation details from clients // +----------------------------------------------------------------+ // | Implementation | //+------------------------------------------------------------------+ // Only one implementor // Create the correct implementer object // If the abstraction knows all concrete implementors // Instantiate one of them in its constructor // Decide between them based on the arguments passed to its constructor // Default implementation // Initially selected // Change later based on usage // Delegate decision entirely to another object (factory) // Shared implementor > Handle/subject idiom // Multiple inheritance // Exposed from abstraction // Privately provided by a concrete implementer // to permanently bind an implementation to its interface //+------------------------------------------------------------------+ //|Related patterns | //+------------------------------------------------------------------+ // Abstract factory > creates and configures a specific bridge // adapter // Aimed at making unrelated classes work together // applied to the system after design // bridge > pre-used in the design //+--------------------------------------------------------------------------------+



Attachment download

📎 pattern.mq5 (0.47 KB)

📎patternlauncher.mqh (2.68 KB)

📎 patternorganizer.mqh (2.89 KB)

📎 bridge.mqh (18.93 KB)

Source: MQL5 #30801

Verification code Refresh