DigestCPP

Lets Understand With Example

  • Home
  • Design Principal
  • Design Patterns
  • C++ 11 Features
  • C++11 Multithreading
  • Contact Us

Adapter Design Pattern C++

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:

OLD API (Interface) that’s exposed to client and this CAN NOT be changed.
Adapter that converts the API
Client that’s expecting different API than OLD API

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:

By DigestCPP.com

Class Diagram with composition:

By DigestCPP.com

Class Diagram of real example:

By DigestCPP.com

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

Primary Sidebar




DigestCPP © 2023. All rights reserved.

    About Privacy Policy Terms and Conditions Contact Us Disclaimer