Home [Design Patterns] Adapter Pattern
Post
Cancel

[Design Patterns] Adapter Pattern

Definition

The adapter pattern converts the interface of a class into another interface that a client expects. The adapter lets classes work together that couldn’t otherwise because of the incompatible interfaces.

Scenario

When we use a third-party library (dependencies) in our project, its API might not be compatible. For example, the library provides API func(int a, char* b, float c) in version 1.0 and func(char* b, int a, float c) in version 2.0. In our project, we want to use func. If we update the library recklessly, it may cause a ripple effect everywhere func is used.

We would want to wrap the library so that when using it in our code, the underlying behavior does not change, and the interface is adaptable. This does not add additional behavior.

Class Diagram

Adapter Pattern Adapter Pattern

Client is some piece of code that wants to call the dependency. ITarget specifies the interface for which the adapter (Adapter) needs to follow. Adapter uses the dependency (Adaptee) method SpecificRequest and completes a specific task.

Used Cases

  • When using other third-party libraries, in order not to cause a ripple effect when their interfaces have changed, we can use the adapter to make the effect stop at the outermost layer of the software.
  • We want to change a method’s signature that is scattered everywhere or that is subject to change in the future.

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// adapter.h
#ifndef __ADAPTER_H__
#define __ADAPTER_H__

#include <memory>

class ITarget {
public:
    virtual void Request() = 0;
};

class Adaptee {
public:
    void SpecificRequestAPI();
};

class Adapter : public ITarget {
private:
    std::unique_ptr<Adaptee> adaptee_;

public:
    Adapter(std::unique_ptr<Adaptee>&& adaptee);
    void Request() override;
};

#endif  //__ADAPTER_H__
1
2
3
4
5
6
7
8
9
10
// adapter.cpp
#include "adapter.h"

#include <iostream>

Adapter::Adapter(std::unique_ptr<Adaptee>&& adaptee) { adaptee_ = std::move(adaptee); }

void Adapter::Request() { adaptee_->SpecificRequest(); }

void Adaptee::SpecificRequestAPI() { std::cout << "[Adaptee] Calling SpecificRequestAPI()" << std::endl; }
1
2
3
4
5
6
7
8
9
10
11
// main.cpp
#include "adapter.h"

int main() {
    {
        std::unique_ptr<ITarget> dependency = std::make_unique<Adapter>(std::make_unique<Adaptee>());
        dependency->Request();
    }

    return 0;
}

Reference

This post is licensed under CC BY 4.0 by the author.