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