当前位置:网站首页>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
边栏推荐
- 買賣股票費用計算
- 1182:合影效果
- Automatic conversion - interview questions
- A strange execution plan. One table in the association query is not associated with any other tables
- JSON数据与List集合之间的正确转换
- 桥接模式(Bridge)
- P2394 yyy loves Chemistry I
- 组合模式(Composite Pattern)
- SQL optimization experience: from 30248 seconds to 0.001 seconds
- Test cases for learning the basic content of software testing (II)
猜你喜欢

函数的分文件编写

Dolphin scheduler uses system time

Calcul des frais d'achat et de vente d'actions

Explain final, finally, and finalize

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

HDI的盲孔设计,你注意到这个细节了吗?

Dbeaver连接人大金仓KingbaseES V8(超详细图文教程)

Unity AssetBundle资源打包与资源加载

1182:合影效果

Linux下安装redis 、Windows下安装redis(超详细图文教程)
随机推荐
Key summary VII of PMP examination - monitoring process group (1)
2020-10-27
Virtual machine 14 installing win7 (Figure tutorial)
Campus honey decoration of APP course design (e-commerce platform)
数字人行业爆发在即,市场格局几何?
A strange execution plan. One table in the association query is not associated with any other tables
Basic content learning of software testing (I)
DBeaver安装与使用教程(超详细安装与使用教程)
微信小程序开发日志
全局异常处理器与统一返回结果
Redis5.0 slot migration, free play (single machine migration cluster)
Flip CEP skip policy aftermatchskipstrategy Skippastlastevent() matched no longer matches the Bikeng Guide
The constructor is never executed immediately after new()!!!!!
spark的资源调度和任务调度
When the interviewer asks you to write binarysort in two ways
new URL(“www.jjj.com“)
1180:分数线划定/P1068 [NOIP2009 普及组] 分数线划定
Xiaomi's payment company was fined 120000 yuan, involving the illegal opening of payment accounts, etc.: Lei Jun is the legal representative, and the products include MIUI wallet app
创建多线程的方法---1创建Thread类的子类及多线程原理
桥接模式(Bridge)