Bridge - Structural Design Pattern - MetaTrader 5 Library | MT5 EA Download - MetaTrader 5 Resources
//+------------------------------------------------------------------+ //| 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> #includeNamespace 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
💡 Featured Recommendations
✍️ Latest by the author
- •
- •
- •
- •
- •
- •
📌 Popular topics
- •
- •
- •
- •
- •
- •
- •
- •
🔗 You May Be Interested In
- •
- •
- •
- •
- •
- •