当前位置:网站首页>Adapter mode
Adapter mode
2022-06-28 09:39:00 【Beginner Xiaobai Lu】
Adapter is a structural design pattern , It enables objects with incompatible interfaces to cooperate with each other . Also known as wrapper mode (Wrapper).
The adapter pattern hides the complex transformation process behind the scenes by encapsulating objects . The encapsulated object is not even aware of the adapter . for example , You can use a to convert all data to English units ( Feet and miles ) The adapter encapsulates objects running in meter and kilometer systems .
The adapter can not only convert data in different formats , It also facilitates cooperation between objects that use different interfaces . It works as follows :
The adapter implements an interface compatible with one of the existing objects .
Existing objects can use this interface to safely call adapter methods .
When the adapter method is called, the request is passed to another object in a format and order that is compatible with that object .

client (Client) Is the class that contains the business logic of the current program .
Client interface (Client Interface) It describes the protocols that other classes must follow when cooperating with client code .
service (Service) There are some functional classes in ( Usually from third parties or legacy systems ). The client is not compatible with its interface , Therefore, its function cannot be called directly .
Adapter (Adapter) Is a class that can interact with clients and services at the same time : It encapsulates the service object while implementing the client interface . The adapter accepts calls from the client through the adapter interface , And turn it into a call for the encapsulated service object .
The client code only needs to interact with the adapter through the interface , No need to couple with specific adapter classes . therefore , You can add new types of adapters to the program without modifying the existing code . This is useful when the interface of the service class is changed or replaced : You can create a new adapter class without modifying the client code .
Realization way
- Make sure that the interfaces of at least two classes are incompatible :
- One cannot be modified ( Usually a third party 、 Legacy systems or classes with many existing dependencies ) Functional class of .
- One or more client classes that will benefit from using service classes .
- Declare the client interface , Describe how the client interacts with the service .
- Create an adapter class that follows the client interface . All methods are temporarily empty .
- Add a member variable in the adapter class to save the reference to the service object . Usually, the member variable is initialized through the constructor , But sometimes it's more convenient to pass this variable to the adapter when calling its method .
- Implement all methods of the adapter class client interface in turn . The adapter delegates the actual work to the service object , It is only responsible for the conversion of interface or data format .
- The client must use the adapter through the client interface . thus , You can modify or extend the adapter without affecting the client code .
advantage
- Under the single responsibility principle, you can separate the interface or data conversion code from the main business logic of the program .
- Opening and closing principle . As long as the client code interacts with the adapter through the client interface , You can add a new type of adapter to your program without modifying the existing client code .
shortcoming
The overall complexity of the code increases , Because you need to add a series of interfaces and classes . Sometimes it's easier to change the service class directly to make it compatible with other code .
Relationships with other models
- Bridges are usually designed in the early stages of development , Enables you to separate parts of the program for development . On the other hand , Adapters are usually used in existing programs , Let incompatible classes cooperate well .
- The adapter can modify the interface of existing objects , Decoration can strengthen the object function without changing the object interface . Besides , Decoration also supports recursive composition , The adapter cannot achieve .
Adapters can provide different interfaces for encapsulated objects , Agents can provide the same interface for objects , Decoration can provide an enhanced interface for objects . - Appearance defines a new interface for existing objects , The adapter will try to use the existing interface . Adapters typically encapsulate only one object , Appearances usually act on the entire object subsystem .
- The bridge 、 Status and policy ( To some extent, it includes adapters ) The interface of the pattern is very similar . actually , They are all based on composite patterns —— Delegate work to other objects , But they also solved different problems . Patterns are not just recipes for organizing code in a particular way , You can also use them to discuss problems solved by patterns with other developers .
Example 1
The problem of square nails and round holes , What we need to do is make the square nail fit the round hole .
The adapter makes the square nail pretend to be a round nail (RoundPeg), Its radius is equal to the square nail (SquarePeg) Half of the diagonal of the cross section ( That is, the radius of the smallest circumscribed circle that can accommodate the square nail ).
// ClientInterface.h
#ifndef CLIENT_INTERFACE_H_
#define CLIENT_INTERFACE_H_
// Round nail : Client interface , stay C++ Defined as an abstract base class
class RoundPeg {
public:
RoundPeg() {
}
virtual int get_radius() = 0;
};
#endif // CLIENT_INTERFACE_H_
Adapter.h:
// Adapter.h:
#ifndef ADAPTER_H_
#define ADAPTER_H_
#include <cmath>
#include "Service.h"
#include "ClientInterface.h"
// Square nail adapter : The adapter allows the client to put the square nail into the round hole
class SquarePegAdapter : public RoundPeg {
public:
explicit SquarePegAdapter(SquarePeg* sp) : square_peg_(sp) {
}
int get_radius() override {
return square_peg_->get_width() * sqrt(2) / 2;
}
private:
SquarePeg* square_peg_;
};
#endif // ADAPTER_H_
Service.h:
#ifndef SERVICE_H_
#define SERVICE_H_
// Square nail : Adapter class , That is, classes that are incompatible with the client
class SquarePeg {
public:
explicit SquarePeg(int w) : width_(w) {
}
int get_width() {
return width_;
}
private:
int width_;
};
#endif // SERVICE_H_
Client.h:
#ifndef CLIENT_H_
#define CLIENT_H_
#include "ClientInterface.h"
// circular hole : Client class
class RoundHole {
public:
explicit RoundHole(int r) : radius_(r) {
}
int get_radius() {
return radius_;
}
bool isFit(RoundPeg* rp) {
return radius_ >= rp->get_radius();
}
private:
int radius_;
};
#endif // CLIENT_H_
main.cpp
#include <iostream>
#include "Client.h"
#include "Adapter.h"
int main() {
// The radius is 10 A round hole in the
RoundHole* hole = new RoundHole(10);
// The radii are 5 and 20 Large and small square nails + Their adapters
SquarePeg* samll_square_peg = new SquarePeg(5);
SquarePeg* large_square_peg = new SquarePeg(20);
SquarePegAdapter* small_square_peg_adapter = new SquarePegAdapter(samll_square_peg);
SquarePegAdapter* large_square_peg_adapter = new SquarePegAdapter(large_square_peg);
// hole->isFit(samll_square_peg); // Compiler error
// hole->isFit(large_square_peg); / / Compiler error
if (hole->isFit(small_square_peg_adapter)) {
std::cout << "small square peg fits the hole" << std::endl;
} else {
std::cout << "small square peg don't fit the hole" << std::endl;
}
if (hole->isFit(large_square_peg_adapter)) {
std::cout << "large square peg fits the hole" << std::endl;
} else {
std::cout << "large square peg don't fit the hole" << std::endl;
}
}
Compile operation
$g++ -g main.cpp -o adapter -std=c++11
$./adapter
small square peg fits the hole
large square peg don't fit the hole
Example 2
hypothesis , Now there are all kinds of animals , It's all ready-made , There are cats 、 Dog . They all have their own methods, for example , Lie down , Roll, etc , But what? , Their interfaces are different . To make the owner let the cat 、 The dog's interface for action is consistent , You need an adapter . Because of the language barrier , A meow meow , A woof woof .
adpter.h
#include <iostream>
class DOG {
public:
void Dog_Bedding() {
std::cout << " Little dog , Please lie down " << std::endl; }
void Dog_Roll() {
std::cout << " Little dog , Please roll " << std::endl; }
};
class CAT {
public:
void Cat_Bedding() {
std::cout << " little cat , Please lie down " << std::endl; }
void Cat_Roll() {
std::cout << " little cat , Please roll " << std::endl; }
};
class Target {
public:
virtual void Bedding()=0; // External symbol
virtual void Roll()=0;
};
class adpter_cat : public Target {
public:
adpter_cat(CAT* c) : cat_(c) {
}
void Bedding() {
cat_->Cat_Bedding(); }
void Roll() {
cat_->Cat_Roll(); }
private:
CAT* cat_;
};
class adpter_dog : public Target {
public:
adpter_dog(DOG* d) : dog_(d) {
}
void Bedding() {
dog_->Dog_Bedding(); }
void Roll() {
dog_->Dog_Roll(); }
private:
DOG* dog_;
};
main.cpp
// #include "Adpter_cat.h"
// #include "Adpter_dog.h"
// #include "cat.h"
// #include "dog.h"
#include "adpter.h"
int main() {
CAT* cat = new CAT();
DOG* dog = new DOG();
adpter_cat ac(cat);
adpter_dog ad(dog);
ac.Bedding();
ac.Roll();
ad.Bedding();
ad.Roll();
}
Running results
little cat , Please lie down
little cat , Please roll
Little dog , Please lie down
Little dog , Please roll
边栏推荐
- 什么是在线开户?现在网上开户安全么?
- How do I open an account on my mobile phone? Is it safe to open an account online now?
- 如何查看谷歌浏览器保存的网页密码
- ==和eqauls()的区别
- 手机号、邮箱正则验证[通俗易懂]
- 1180: fractional line delimitation /p1068 [noip2009 popularization group] fractional line delimitation
- 静态代码块永远先执行? 格局小了!!!
- abnormal
- 玩玩sftp上传文件
- PMP needs to master its own learning methods
猜你喜欢

Automatic conversion - interview questions

DBeaver安装与使用教程(超详细安装与使用教程)

104. maximum depth of binary tree

Write a simple timeline

Basic knowledge of hard disk (head, track, sector, cylinder)

小米旗下支付公司被罚 12 万,涉违规开立支付账户等:雷军为法定代表人,产品包括 MIUI 钱包 App

1181:整数奇偶排序

Decision table method for basic content learning of software testing (2)

Prototype chain JS
理解IO模型
随机推荐
Check whether the table contains rows SQL Server 2005 - check whether a table contains rows or not SQL Server 2005
Machine virtuelle 14 installer win7 (tutoriel)
Stutter participle_ Principle of word breaker
剑指Offer | 斐波那契数列
The concept of "tree structure" perfectly interprets the primary and secondary of things
如何查看谷歌浏览器保存的网页密码
June 27, 2022: give a 01 string with a length of N. now please find two intervals so that the number of 1 is equal and the number of 0 is equal in the two intervals. The two intervals can intersect bu
结巴分词器_分词器原理
硬盘基本知识(磁头、磁道、扇区、柱面)
Static page of pinyougou mall
构造方法绝不是在new()之后就立马执行!!!!!
Explain final, finally, and finalize
Multithreading concurrent parallel threaded process
Regular verification of mobile phone number and email [easy to understand]
How to reduce the risk of project communication?
Thread lifecycle
JVM family (2) - garbage collection
线程的生命周期
数字人行业爆发在即,市场格局几何?
两道面试小Demo