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

Decorator - Structural Design Patterns - MetaTrader 5 Library - MT4/MT5 Resources

author EAcpu | 3 reads | 0 comments |
//+------------------------------------------------------------------+
//| decorator.mqh |
//| 2019-2020, Dimitri Pecherica|
//| 792112@gmail.com |
//+------------------------------------------------------------------+
//|Decorator<structural design pattern |
//+------------------------------------------------------------------+
// Design patterns: elements of reusable object-oriented software
// gof > Erich Gamma, Richard Helm, Ralph Johnson, John Freesides
// Published in 1994
//+------------------------------------------------------------------+
//|Intent |
//+------------------------------------------------------------------+
// Dynamically attach (attached responsibilities) to the object
// Provides - a flexible alternative to subclassing - for extension
//    Function
//+------------------------------------------------------------------+
//|Benefits|
//+------------------------------------------------------------------+
// Variable aspect > No responsibilities for subclassed objects
// code refactoring
// Cannot easily change classes > yet > adapters, visitors
// Extend functionality through subclassing
// Solution > Composition/Delegation of Composite Behavior
// also> bridge, responsibility chain, compound,
// Observer, strategy
//+------------------------------------------------------------------+
//|Applicability |
//+------------------------------------------------------------------+
// Add responsibilities — to each object —
// Dynamically and transparently - does not affect other objects
// For revocable responsibilities
// When extension via subclassing is impractical
// Sometimes there may be a large number of independent extensions
// And will generate a large number of subclasses to support
// each combination
// Or the class definition may be hidden
// Otherwise, subclassing cannot be done
//+------------------------------------------------------------------+
//|Structure |
//+------------------------------------------------------------------+
//
// |Component|<------------------------------------------------+
// |----------| |
// |Operation()| |
// ^ |
// | |
// +-----------+----------------+ |
// | | Components |
// |ConcreteComponent| | Decorator |------------+
// |------------------| |------------------------|
// |Operation() | |Operation() |
// || component.Operation()|
// ^
// |
// +----------------++----------------+
// | |
// |ConcreteDecoratorA| | Concrete decorator B |
// |--------------------------------| |------------------------|</span> // |Operation() | |Operation() | // |--------------------------------| |Decorator::Operation()| // |added_state | |AddedBehavior() | // |AddedBehavior() | // #include Namespace Decorator { //+------------------------------------------------------------------+ //| Actor> Component | //+------------------------------------------------------------------+ Class Component // Definition — Object's interface // Responsibilities can be added dynamically { public : virtual blank operation( blank ) = 0 ; }; //+--------------------------------------------------------------------------------+ //| Actor > Component | //+------------------------------------------------------------------+ Class Component // Definition — Interface — Object maintains a reference to the Component object . Conforms to the component's interface { public : component * component; void operation( void ); }; //+------------------------------------------------------------------+ //| Actor > Decorator | //+------------------------------------------------------------------+ void Decorator ::Operation( void ) { if ( check pointer (component) > 0 ) { Component.Operation(); } } // +------------------------------------------------------------------+ // | Actor > Concrete Component //+------------------------------------------------------------------+ Class : Concrete Component // Defines objects to which additional responsibilities can be attached { public : blank operation( blank ); }; //+ ------------------------------------------------------------------ + //| Actor > Concrete Component | //+------------------------------------------------------------------+ void Concrete Component::Operation ( blank ) { print ( "Concrete Action" ); } // +------------------------------------------------------------------+ //| Actor > Concrete Decorator | //+------------------------------------------------------------------+ //| Actor> ConcreteDecorator>a | //+------------------------------------------------------------------+ class ConcreteDecoratorA :popularDecorator { protected : StringAddState ; populace :ConcreteDecoratorA( void ); voidAddState ( void ); }; // +-----------------------------------------------------------------+ //| ConcreteDecoratorA::ConcreteDecoratorA( void ): addState( "add state" ) { } //+----------------------------------------------------------------+ //|Participant > Concrete Decorator > a | //+----------------------------------------------------------------------------------+ Blank ConcreteDecoratorA::Operation( blank ) { Decorator::Operation(); print (AddState); } //+----------------------------------------------------------------+ //|Participant > Concrete Decorator > b | //+------------------------------------------------------------------+ Class Concrete Decorator:: Concrete Decorator { public : void AddedBehavior( blank ); void operation( blank ); }; //+----------------------------------------------------------------------------------+ //|Participant > Concrete Decorator > b | //+------------------------------------------------------------------+ Blank ConcreteDecoratorB::AddedBehavior( void ) { Print ( "AddedBehavior" ); } //+------------------------------------------------------------------+ //|Participant > Concrete Decorator > b | //+------------------------------------------------------------------+ Blank ConcreteDecoratorB::Operation( Blank ) { Decorator::Operation(); AddBehavior(); } //+------------------------------------------------------------------+ //|Participant > Client | //+------------------------------------------------------------------+ Class Client: Crowd Client Example { People : String Output( Blank ); Blank Running( Blank ); }; String Client::Output( Blank ) { Return __Function__ ;} //+------------------------------------------------------------------+ //|Cooperation | //+------------------------------------------------------------------+ Blank Client::Run( Blank ) // Decorator // forwards --- the request -- to its component object // which may optionally perform additional operations before and after // forwarding the request { component * component = new concrete component(); decorator * decorator_a = new concrete decorator A(); decorator * decorator_b = new concrete decorator B(); decorator_a.component=component; decorator_b.component=decorator_a; decorator_b.Operation(); //--- Delete component; delete decorator_a; delete decorator_b; } } //+--------------------------------------------------------------------------------+ //|Output | //+--------------------------------------------------------------------------------+ // Decorator::Client::Output // Specific operation // Add state // Added behavior //+--------------------------------------------------------------------------------+ //|Consequences | //+------------------------------------------------------------------+ // More flexible than static inheritance // Responsibilities can be added and removed at runtime // Just attach and detach them // Easily add properties twice <span class="comment">// Avoid feature-rich classes higher up in the hierarchy // Add functionality incrementally // Define new decorators independently // From the object classes they extend // Even for unforeseen extensions // Decorators and their components are not identical // Many small objects //+--------------------------------------------------------------------------------+ // | Implementation | //+--------------------------------------------------------------------------------+ // Interface consistency > Decorator components // Omit abstract decorator classes - if single responsibility // Keep components lightweight // Change the object's appearance versus changing its internals > Strategy // + -------------------------------------------------------------------------------+ // | Related Patterns | // + -------------------------------------------------------------------------------+ // Adapter > Will provide a completely new interface to the object // Decorator > Change the object's responsibilities, not its interface // Synthetic // Decorator - is a degenerate composite with only one component - // Not suitable for object aggregation // Strategy > Change the internal structure of the object // Decorator > Change the appearance of an object //+------------------------------------------------------------------+



Attachment download

📎 pattern.mq5 (2.21 KB)

📎 patternorganizer.mqh (13.31 KB)

📎 decorator.mqh (22.3 KB)

Source: MQL5 #30969

Verification code Refresh