//---adapter---------------------------------------------------------- // structural design pattern //---adapter > intent // convert the interface of a class into another expected interface // classes with incompatible interfaces can work together //---adapter > benefits----------------------------------------------- // interface to an object my vary // refactoring problem resolved // inability to alter classes conveniently // also decorator, visitor //---adapter > applicability------------------------------------------ // interface does not match the one you need // reusable class // cooperates with unrelated/unforeseen classes // object adapter // parent's interface is adapted // when subclassing is impractical //---adapter > class adapter > structure------------------------------ // // |Client|------>| Target | | Adaptee | // |---------| |-----------------| // |Request()| |SpecificRequest()| // ^ ^ // | | // +--------+ +---------+ // | | implementation // | Adapter | // |-------------------| // |Request() | // | SpecificRequest() | // #include <SRCPatternsPatternOrganizer.mqh> namespace AdapterClass { //---class adapter > participants------------------------------------- interface Target //defines the domain-specific interface that client uses { void Request(); }; //---class adapter > participants------------------------------------- class Adaptee //defines an existing interface that needs adapting { public: void SpecificRequest(); }; void Adaptee::SpecificRequest(void) { Print("Adaptee is executing the specific request"); } //---class adapter > participants------------------------------------- // adapter // adapts the interface of adaptee to the target interface //---inherit from target // structural twin pattern // simulates multiple inheritance from target and adaptee class Adapter; class AdapterAsTarget:public Target { public: Adapter* asAdaptee; void Request(); }; void AdapterAsTarget::Request() { printf("Operation requested from adapter: re-directing to adaptee..."); asAdaptee.SpecificRequest(); } //---inherit from adaptee directly class Adapter:public Adaptee { public: AdapterAsTarget* asTarget; Adapter(); ~Adapter(); }; void Adapter::Adapter(void) { asTarget=new AdapterAsTarget; asTarget.asAdaptee=&this; } void Adapter::~Adapter(void) {delete asTarget;} //---class adapter > participants------------------------------------- class Client:public ClientExample // collaborates with objects conforming to the target interface { public: string Output(); void Run(); }; string Client::Output() {return __FUNCTION__;} //---class adapter > collaborations----------------------------------- void Client::Run() // clients call operations on an adapter instance // adapter calls adaptee operations that carry out the request { Adapter adapter; Target* target=adapter.asTarget; target.Request(); } } //---class adapter > output------------------------------------------- // Structural::AdapterClass::Client::Output // Operation requested from adapter: re-directing to adaptee... // Adaptee is executing the specific request //---adapter > object adapter > structure----------------------------- // // |Client|----->| Target | +-->| Adaptee | // |---------| | |-----------------| // |Request()| | |SpecificRequest()| // ^ | // | | // | Adapter |---+ // |---------------------------| // |Request() | // | adaptee.SpecificRequest() | // namespace AdapterObject { //---object adapter > participants------------------------------------ interface Target //defines the domain-specific interface that client uses { void Request(); }; //---object adapter > participants------------------------------------ class Adaptee //defines an existing interface that needs adapting { public: void SpecificRequest(); }; void Adaptee::SpecificRequest(void) {Print("Specific Request");} //---object adapter > participants------------------------------------ class Adapter:public Target // adapts the interface of adaptee to the target interface { public: void Request(); protected: Adaptee adaptee; }; void Adapter::Request(void) { printf("Operation requested: Now re-directing to..."); adaptee.SpecificRequest(); } //---object adapter > participants------------------------------------ class Client:public ClientExample // collaborates with objects conforming to the target interface { public: string Output(); void Run(); }; string Client::Output() {return __FUNCTION__;} //---object adapter > participants------------------------------------ void Client::Run() // clients call operations on an adapter instance // adapter calls adaptee operations that carry out the request { Target* target=new Adapter; target.Request(); delete target; } } //---object adapter > output------------------------------------------ // Structural::AdapterObject::Client::Output // Operation requested: Now re-directing to... // Specific Request //---adapter > consequences------------------------------------------- // adapts adaptee to target by committing to a concrete adapter class // class adapter won't adapt a class with all its subclasses // overriding of adaptee's behavior is possible // introduces only one object // direct adaptee access // how much adapting does adapter do // simple interface conversion // names of operations are changed // entirely different set of operations is supported // pluggable adapters // two-way adapters for transparency // multiple inheritance // interfaces of the adapted classes are substantially different // conforms to both of the adapted classes // can work in either system //---adapter > implementation----------------------------------------- // class adapters in c++ // inherit publicly from target and privately from adaptee // subtype of target but not of adaptee // pluggable adapters // interface for adaptee should be narrow // abstract operations may be used // delegate objects may be used // requests are forwarded to a delegate object // access the hierarchical structure // mixing classes together // easier than a new subclass with its operations // parameterized adapters // convenient alternative to subclassing // interface adaptation is built into a class //---adapter > related patterns--------------------------------------- // bridge // interface/implementation are separated // easy to change independently // adapter changes the existing interface // decorator // enhances object without changing its interface // more transparent // supports recursive composition // proxy // object's surrogate // does not change its interface //+------------------------------------------------------------------+