设计模式:适配器模式

回答

“适配器模式是一种结构型设计模式,它用于将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而无法一起工作的类能够协同工作。

适配器模式主要有两种类型:类适配器和对象适配器。

  • 类适配器:通过继承适配者类,并实现目标接口,适配器可以直接调用适配者类的方法。
  • 对象适配器:通过组合的方式,适配器持有适配者类的实例,并在目标接口的方法中调用适配者的方法。

例如,在一个需要兼容旧系统和新系统的场景中,我们可以使用适配器模式,创建适配器类将新系统的接口转换成旧系统的接口,避免对旧系统进行修改。”

设计模式:适配器模式

image-20240904145904340

用充电头来举例,适配器是将220V的交流电变成符合手机能够使用的电压输入手机,实现兼容。

1. 什么是适配器模式?

适配器模式(Adapter Pattern)是一种结构型设计模式,它的主要作用是将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而无法一起工作的类能够协同工作。

适配器模式通常用于现有系统与第三方库、工具或者新系统的接口不兼容的情况下,通过引入一个适配器来解决接口的不兼容问题,而不需要修改现有代码。

2. 适配器模式的类型

适配器模式主要有两种类型:

  • 类适配器(Class Adapter):通过多重继承实现适配器功能。适配器继承了目标接口和被适配的类,使得适配器可以直接调用被适配类的方法,并对外提供目标接口的实现。
  • 对象适配器(Object Adapter):通过组合的方式实现适配器功能。适配器类持有一个被适配类的实例,通过调用这个实例的方法来实现目标接口的功能。

3. 适配器模式的结构

适配器模式通常包含以下几个角色:

  • 目标接口(Target):定义客户端所期望的接口。
  • 适配者类(Adaptee):定义一个已经存在的接口,它需要适配。
  • 适配器类(Adapter):适配器类通过实现目标接口,并组合或继承适配者类,实现接口转换的功能。
  • 客户端(Client):使用目标接口进行编程,通过适配器来访问适配者类的功能。

image-20240904151437766

4. 适配器模式的实现

我们来分别看一下类适配器和对象适配器的实现方式。

类适配器模式(Class Adapter)

1. 定义目标接口和适配者类

1
2
3
4
5
6
7
8
9
10
11
// 目标接口
public interface Target {
void request();
}

// 适配者类,拥有不兼容的接口
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: Handling request in a specific way.");
}
}

2. 实现适配器类

1
2
3
4
5
6
7
8
// 类适配器,继承了适配者类,同时实现目标接口
public class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
// 调用适配者类的方法
specificRequest();
}
}

3. 使用适配器

1
2
3
4
5
6
public class Client {
public static void main(String[] args) {
Target target = new ClassAdapter();
target.request(); // 输出 "Adaptee: Handling request in a specific way."
}
}

对象适配器模式(Object Adapter)

1. 定义目标接口和适配者类

1
2
3
4
5
6
7
8
9
10
11
// 目标接口
public interface Target {
void request();
}

// 适配者类,拥有不兼容的接口
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: Handling request in a specific way.");
}
}

2. 实现适配器类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 对象适配器,通过组合的方式使用适配者类
public class ObjectAdapter implements Target {
private Adaptee adaptee;

public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}

@Override
public void request() {
// 委托调用适配者类的方法
adaptee.specificRequest();
}
}

3. 使用适配器

1
2
3
4
5
6
7
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request(); // 输出 "Adaptee: Handling request in a specific way."
}
}

适配器模式的优点

  • 解耦:通过引入适配器,使得原本不兼容的类可以一起工作,降低了客户端与系统之间的耦合度。
  • 灵活性:适配器模式支持类适配器和对象适配器两种方式,分别适用于不同的场景。
  • 复用性:可以复用现有的类,无需修改已有代码,通过适配器扩展系统功能。

适配器模式的缺点

  • 复杂性增加:引入适配器后,系统的复杂性可能增加,尤其是在系统中有大量接口和适配器时。
  • 性能开销:在对象适配器模式中,适配器需要持有适配者类的实例,可能会带来一些性能开销。