介绍
适配器模式将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。
实现
对象适配器模式
myclass.h
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class Target { // 目标类
public:
virtual void request() = 0;
};
class Adaptee { // 适配者类
public:
void specificRequest();
};
class Adapter : public Target { // 适配器类
public:
Adapter(Adaptee *adaptee);
void request() override;
private:
Adaptee *m_adaptee;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
Adapter::Adapter(Adaptee *adaptee) {
m_adaptee = adaptee;
}
void Adapter::request() {
if (m_adaptee) {
m_adaptee->specificRequest();
}
}
void Adaptee::specificRequest() {
std::cout << "Adaptee被适配" << std::endl;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
Adaptee *adaptee = new Adaptee;
Target *target = new Adapter(adaptee);
target->request();
delete target;
delete adaptee;
return 0;
}
类适配器模式
myclass.h
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class Target { // 目标类
public:
virtual void request() = 0;
};
class Adaptee { // 适配者类
public:
void specificRequest();
};
class Adapter : public Target, public Adaptee { // 适配器类
public:
void request() override;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
void Adapter::request() {
specificRequest();
}
void Adaptee::specificRequest() {
std::cout << "Adaptee被适配" << std::endl;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
Target *target = new Adapter();
target->request();
delete target;
return 0;
}
双向适配器
myclass.h
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class Target { // 目标类
public:
void request();
};
class Adaptee { // 适配者类
public:
void specificRequest();
};
class Adapter { // 适配器类
public:
Adapter(Target *target);
Adapter(Adaptee *adaptee);
void request();
void specificRequest();
private:
Target *m_target;
Adaptee *m_adaptee;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
void Target::request() {
std::cout << "Target被适配" << std::endl;
}
Adapter::Adapter(Target *target) {
m_target = target;
}
Adapter::Adapter(Adaptee *adaptee) {
m_adaptee = adaptee;
}
void Adapter::request() {
if (m_adaptee) {
m_adaptee->specificRequest();
}
}
void Adapter::specificRequest() {
if (m_target) {
m_target->request();
}
}
void Adaptee::specificRequest() {
std::cout << "Adaptee被适配" << std::endl;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
Target *target = new Target();
Adaptee *adaptee = new Adaptee();
Adapter *adapter = new Adapter(target);
adapter->specificRequest();
delete adapter;
adapter = new Adapter(adaptee);
adapter->request();
delete adapter;
delete adaptee;
delete target;
return 0;
}
缺省适配器模式
myclass.h
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class ServiceInterface { // 适配者接口
public:
virtual void request() = 0;
virtual void request2() = 0;
virtual void request3() = 0;
};
class AbstractService : public ServiceInterface { // 缺省适配器类
public:
virtual void request() override;
virtual void request2() override;
virtual void request3() override;
};
class Adaptee { // 适配者类
public:
void specificRequest();
};
class Adapter : public AbstractService { // 具体适配器类
public:
Adapter(Adaptee *adaptee);
void request() override;
private:
Adaptee *m_adaptee;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
Adapter::Adapter(Adaptee *adaptee) {
m_adaptee = adaptee;
}
void Adapter::request() {
if (m_adaptee) {
m_adaptee->specificRequest();
}
}
void Adaptee::specificRequest() {
std::cout << "Adaptee被适配" << std::endl;
}
void AbstractService::request() {
std::cout << "缺省函数request" << std::endl;
}
void AbstractService::request2() {
std::cout << "缺省函数request2" << std::endl;
}
void AbstractService::request3() {
std::cout << "缺省函数request3" << std::endl;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
Adaptee *adaptee = new Adaptee();
Adapter *adapter = new Adapter(adaptee);
adapter->request();
adapter->request2();
adapter->request3();
delete adapter;
delete adaptee;
return 0;
}
总结
优点
-
将目标类和适配者类解耦。通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
-
增加了类的透明性和复用性。将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者类的复用性,同一个适配者类可以在多个不同的系统中复用。
-
灵活性和扩展性都非常好。通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合开闭原则。
缺点
-
对于Java、C#等不支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配者。
-
适配者类不能为最终类,例如在Java中不能为final类,C#中不能为sealed类。
-
在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定的局限性。
适用场景
-
系统需要使用一些现有的类,而这些类的接口(例如方法名)不符合系统的需要,甚至没有这些类的源代码。
-
想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作。
练习
对象适配器模式
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class Encryption { // 目标类
public:
virtual std::string encrypt(std::string data) = 0;
};
class ThirdLib { // 适配者类
public:
std::string specificEncrypt(std::string data);
std::string specificDecrypt(std::string data);
};
class AdapterEncyption : public Encryption { // 适配器类
public:
AdapterEncyption(ThirdLib *thirdLib);
~AdapterEncyption();
std::string encrypt(std::string data) override;
private:
ThirdLib *m_thirdLib;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
AdapterEncyption::AdapterEncyption(ThirdLib *thirdLib) {
m_thirdLib = thirdLib;
}
AdapterEncyption::~AdapterEncyption() {
if (m_thirdLib) {
delete m_thirdLib;
}
}
std::string AdapterEncyption::encrypt(std::string data) {
if (m_thirdLib) {
return m_thirdLib->specificEncrypt(data);
}
return data;
}
std::string ThirdLib::specificEncrypt(std::string data) {
return "加密后的" + data;
}
std::string ThirdLib::specificDecrypt(std::string data) {
return "解密后的" + data;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
ThirdLib *thirdLib = new ThirdLib();
Encryption *encryption = new AdapterEncyption(thirdLib);
std::string data = encryption->encrypt("口令");
std::cout << data << std::endl;
data = encryption->encrypt("邮箱");
std::cout << data << std::endl;
return 0;
}
类适配器模式
myclass.h
cpp
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
class Encryption { // 目标类
public:
virtual std::string encrypt(std::string data) = 0;
};
class ThirdLib { // 适配者类
public:
std::string specificEncrypt(std::string data);
std::string specificDecrypt(std::string data);
};
class AdapterEncyption : public Encryption, public ThirdLib { // 适配器类
public:
AdapterEncyption();
~AdapterEncyption();
std::string encrypt(std::string data) override;
};
#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
cpp
//
// Created by yuwp on 2024/1/12.
//
#include "myclass.h"
AdapterEncyption::AdapterEncyption() {
}
AdapterEncyption::~AdapterEncyption() {
}
std::string AdapterEncyption::encrypt(std::string data) {
return specificEncrypt(data);
}
std::string ThirdLib::specificEncrypt(std::string data) {
return "加密后的" + data;
}
std::string ThirdLib::specificDecrypt(std::string data) {
return "解密后的" + data;
}
main.cpp
cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
Encryption *encryption = new AdapterEncyption();
std::string data = encryption->encrypt("口令");
std::cout << data << std::endl;
data = encryption->encrypt("邮箱");
std::cout << data << std::endl;
delete encryption;
return 0;
}