Design Pattern means that “we had some problem then we found the solution and gave name to this solution” and Adapter is also one of the solution so we need to find the problem that Adapter has solved and how ?
This design pattern comes under Structural Category .
================================================================
C++ Adapter Design Pattern :
Standard Definition:
Adapter Design Pattern convert the interface of class into another interface that client is expecting. Adaptor lets classes work together that could not work because of incompatible interface. It resolves the interface conflict, make the code workable. It helps us to work with legacy code when we want to use old API.
Technical Explanation:
Adapter Pattern says that (I will break down the above standard definition) :
- convert the interface of a class into another interface that client is expecting : There is interface conflict and we need to convert the interface and make is understandable so that client can understand and use it(client is expecting).
- Adapter lets classes work together that could not otherwise because of incompatible interface : Adapter makes two classes work together otherwise they would have not worked together due to interface conflict.
In layman language:
We have old code and its working from many years and we want to use it in new module but we CANNOT reuse due to interface conflicts so solution is “Adapter”, It will give new API that client expect and it will resolve the interface conflict (we can use old API).
Description with the help of image:
Adapter Example:
Execution of Simulator and Actual Device with same API.
Purpose /Objective:
- To resolve interface conflict, can work with old API.
- Provide the API that client expect.
- Easily extend the OLD API to support simulator (see below code).
- In future, we can extend the new API (by adding new Adaptee) without disturbing the client code.
We can implement Adapter Pattern in two ways:
- Using Private inheritance
- Using Composition.
Class Diagram with Private Inheritance:
Class Diagram with composition:
Class Diagram of real example:
source code in c++ with real example:
/* * File:adapter.cpp * This file is described the adapter Design Pattern with help of example * Author: Aplha * Date: 29 Dec 2020 */ //Header file #include<iostream> //Target interface class ITarget { public: virtual void Start()=0; virtual void Stop()=0; virtual void SetMotorType(std::string) = 0; }; //Motor Interface class IMotor { public: virtual void StartMotor()=0; virtual void StopMotor()=0; }; //Actual Motor Class class ActualMotor:public IMotor { void StartMotor() {std::cout<<"Actual Motor Start, call driver app"<<std::endl;} void StopMotor() {std::cout<<"Actual Motor Stop, call driver app"<<std::endl;} }; // Motor Simulator Class class MotorSimulator:public IMotor { void StartMotor() {std::cout<<"Motor Simulator Start for testing"<<std::endl;} void StopMotor() {std::cout<<"Motor Simulator Stop for testing"<<std::endl;} }; //Adapter Class class Adapter:public ITarget { IMotor* mp; Adapter(const Adapter &other) = delete; // Disallow copying void operator=(const Adapter &) = delete;// Disallow copying public: Adapter(); ~Adapter(); void Start(); //Get interface from Base class void Stop(); //Get interface from Base class void SetMotorType(std::string str); }; //Adapter definition Adapter::Adapter():mp(nullptr){} Adapter::~Adapter() { if(mp) delete mp; } void Adapter::Start() { if(mp) { mp->StartMotor(); } else std::cout<<"Motor is not set"<<std::endl; } void Adapter::Stop() { if(mp) { mp->StopMotor(); } else std::cout<<"Motor is not set"<<std::endl; } void Adapter::SetMotorType(std::string str) { if(str == "ActualMotor") { if(mp) delete mp; mp = new ActualMotor; } else if(str == "SimulatorMotor") { if(mp) delete mp; mp = new MotorSimulator; } else { std::cout<<"Motor type is not available"<<std::endl; if(mp) delete mp; } } //Client int main() { std::cout<<"In Main"<<std::endl; //Create the Target ITarget * tar = new Adapter; //Set the Actual Motor tar->SetMotorType("ActualMotor"); tar->Start(); tar->Stop(); //Set the Simulator Motor tar->SetMotorType("SimulatorMotor"); tar->Start(); tar->Stop(); delete tar; return 0; }
Compilation command:
g++ -std=c++11 adapter.cpp
Output:
In Main Actual Motor Start, call driver app Actual Motor Stop, call driver app Motor Simulator Start for testing Motor Simulator Stop for testing