1. 设计模式原理说明
适配器模式(Adapter Pattern) 是一种结构型设计模式,它允许不兼容的接口协同工作。适配器模式可以将一个类的接口转换成另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式分为两种主要类型:类适配器和对象适配器。
主要角色
- Target(目标接口):这是客户端所期望的接口,客户端通过这个接口与适配器进行交互。
- Adaptee(适配者):这是需要适配的类,它具有不同的接口,但提供了我们需要的功能。
- Adapter(适配器):它是一个适配者类和目标接口之间的适配器,它实现了目标接口,并持有对适配者的引用,通过委托调用适配者的方法。
2. UML 类图及解释
UML 类图
+----------------+ +---------------------+
| Target | | Adaptee |
|----------------| |---------------------|
| + request(): void | + specificRequest(): void|
+----------------+ +---------------------+
+----------------+ |
| Adapter | |
|----------------| |
| - adaptee: Adaptee |
| + request(): void |
+----------------+ |
+----------------+ |
| Client | |
|----------------| |
| + mainMethod(): void |
+----------------+ |
类图解释
- Target:定义了客户端所期望的接口。客户端通过这个接口与适配器进行交互。
- Adaptee:这是需要适配的类,它具有不同的接口,但提供了我们需要的功能。
- Adapter:实现了
Target
接口,并持有对Adaptee
的引用。适配器通过委托调用Adaptee
的方法来实现Target
接口的方法。 - Client:客户端通过
Target
接口与适配器进行交互,从而间接使用Adaptee
的功能。
3. 代码案例及逻辑详解
Java 代码案例
// 目标接口
interface Target {
void request();
}
// 需要适配的类
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee's specificRequest method is called.");
}
}
// 适配器类
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 客户端
class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target adapter = new Adapter(adaptee);
adapter.request(); // 调用适配器的 request 方法
}
}
C++ 代码案例
#include <iostream>
// 目标接口
class Target {
public:
virtual void request() = 0;
virtual ~Target() {}
};
// 需要适配的类
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee's specificRequest method is called." << std::endl;
}
};
// 适配器类
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* adaptee) : adaptee(adaptee) {}
~Adapter() {
delete adaptee;
}
void request() override {
adaptee->specificRequest();
}
};
// 客户端
int main() {
Adaptee* adaptee = new Adaptee();
Target* adapter = new Adapter(adaptee);
adapter->request(); // 调用适配器的 request 方法
delete adapter;
return 0;
}
Python 代码案例
# 目标接口
class Target:
def request(self):
pass
# 需要适配的类
class Adaptee:
def specific_request(self):
print("Adaptee's specific_request method is called.")
# 适配器类
class Adapter(Target):
def __init__(self, adaptee):
self.adaptee = adaptee
def request(self):
self.adaptee.specific_request()
# 客户端
if __name__ == "__main__":
adaptee = Adaptee()
adapter = Adapter(adaptee)
adapter.request() # 调用适配器的 request 方法
Go 代码案例
package main
import "fmt"
// 目标接口
type Target interface {
Request()
}
// 需要适配的类
type Adaptee struct{}
func (a *Adaptee) SpecificRequest() {
fmt.Println("Adaptee's specificRequest method is called.")
}
// 适配器类
type Adapter struct {
adaptee *Adaptee
}
func (a *Adapter) Request() {
a.adaptee.SpecificRequest()
}
// 客户端
func main() {
adaptee := &Adaptee{}
adapter := &Adapter{adaptee: adaptee}
adapter.Request() // 调用适配器的 Request 方法
}
4. 总结
适配器模式 是一种结构型设计模式,它允许不兼容的接口协同工作。适配器模式通过创建一个适配器类来实现目标接口,并持有对适配者类的引用,从而将适配者的方法转换为目标接口的方法。
主要优点
- 提高了类的复用性:通过适配器模式,可以重用现有的类,而不需要修改它们的源代码。
- 增加了灵活性:适配器模式使得系统更易于扩展,因为可以在不修改原有代码的情况下引入新的适配器。
- 分离接口和实现:适配器模式将接口和实现分离,使得系统的职责更加清晰。
主要缺点
- 增加了系统的复杂性:适配器模式会增加系统的类的数量,从而使系统更加复杂。
- 过度设计的风险:如果在没有必要的情况下使用适配器模式,可能会导致过度设计。
总的来说,适配器模式适用于以下场景:
- 当希望使用一个已经存在的类,但其接口不符合需求时。
- 当希望创建一个可以复用的类,该类可以与其他不兼容的类或接口一起工作时。
- 当需要在系统中动态地添加或删除某些功能时,适配器模式可以提供一种灵活的解决方案。