0%

适配器模式

适配器模式(Adapter Pattern):接口转换的桥梁

适配器模式是结构型设计模式的一种,核心思想是将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协同工作的类能够一起工作。它就像生活中的 “转换插头”,让不同规格的设备可以互通,核心功能是 “转换匹配,复用已有功能”。

适配器模式的核心结构

适配器模式包含三个核心角色,通过转换实现接口兼容:

目标角色(Target)

  • 客户端期望的目标接口,定义了客户端需要的方法。
  • 示例:USB接口(客户端设备需要的接口)。

被适配角色(Adaptee)

  • 已存在的旧接口,其功能需要被复用,但与目标接口不兼容。
  • 示例:Type-C接口(已有设备的接口,与 USB 不兼容)。

适配器角色(Adapter)

  • 实现目标接口,并包装被适配对象,将目标接口的方法转换为被适配接口的方法调用。
  • 示例:USB-TypeC转换器(实现 USB 接口,内部调用 Type-C 设备的功能)。

适配器模式的两种实现方式

根据适配器与被适配对象的关系(继承 / 组合),适配器模式分为类适配器对象适配器

1. 类适配器(基于继承)

通过继承被适配类并实现目标接口,将被适配类的方法转换为目标接口的方法。

代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 1. 目标接口(客户端期望的接口)
interface Target {
void request(); // 客户端需要的方法
}

// 2. 被适配类(已有接口,不兼容Target)
class Adaptee {
public void specificRequest() { // 被适配类的方法
System.out.println("被适配类:执行特定功能");
}
}

// 3. 类适配器(继承Adaptee,实现Target)
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
// 将目标接口的request()转换为被适配类的specificRequest()
super.specificRequest();
}
}

// 客户端使用
public class ClassAdapterDemo {
public static void main(String[] args) {
Target target = new ClassAdapter();
target.request(); // 输出:被适配类:执行特定功能
}
}

2. 对象适配器(基于组合)

通过组合被适配对象(持有 Adaptee 的引用)并实现目标接口,更灵活,是更常用的方式。

代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 1. 目标接口(同上)
interface Target {
void request();
}

// 2. 被适配类(同上)
class Adaptee {
public void specificRequest() {
System.out.println("被适配类:执行特定功能");
}
}

// 3. 对象适配器(持有Adaptee的引用,实现Target)
class ObjectAdapter implements Target {
private Adaptee adaptee; // 组合被适配对象

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

@Override
public void request() {
// 转换调用:目标接口方法 → 被适配类方法
adaptee.specificRequest();
}
}

// 客户端使用
public class ObjectAdapterDemo {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request(); // 输出:被适配类:执行特定功能
}
}

两种适配器的对比

方式 实现方式 优点 缺点
类适配器 继承 Adaptee + 实现 Target 结构简单,直接调用父类方法 只能适配单一类,不支持多继承
对象适配器 组合 Adaptee + 实现 Target 可适配多个类(多组合) 需额外包装,代码略复杂

经典应用案例:Spring MVC 的 HandlerAdapter

Spring MVC 中,HandlerAdapter是适配器模式的典型应用,用于适配不同类型的处理器(Handler),使 DispatcherServlet 能统一调用处理器的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 目标接口:HandlerAdapter(定义统一的处理方法)
public interface HandlerAdapter {
boolean supports(Object handler); // 判断是否支持该处理器
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

// 被适配类1:Controller(传统控制器)
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}

// 被适配类2:HttpRequestHandler(HTTP请求处理器)
public interface HttpRequestHandler {
void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}

// 对象适配器1:SimpleControllerHandlerAdapter(适配Controller)
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof Controller; // 支持Controller类型
}
@Override
public ModelAndView handle(...) {
// 转换调用:适配Controller的handleRequest()
return ((Controller) handler).handleRequest(request, response);
}
}

// 对象适配器2:HttpRequestHandlerAdapter(适配HttpRequestHandler)
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
@Override
public ModelAndView handle(...) {
// 转换调用:适配HttpRequestHandler的handleRequest()
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
}

工作原理
DispatcherServlet 通过HandlerAdapterhandle()方法调用不同类型的处理器,无需关心处理器的具体接口(Controller/HttpRequestHandler),实现了请求处理的统一调度。

优缺点分析

优点

  1. 复用现有功能
    无需修改已有类(Adaptee),通过适配器使其适配新接口,复用已有功能,符合开闭原则。
  2. 解耦客户端与被适配类
    客户端仅依赖目标接口,与被适配类隔离,降低耦合度。
  3. 灵活性高
    可通过更换适配器切换不同的被适配类,适应不同场景(如对象适配器可组合多个被适配类)。

缺点

  1. 增加系统复杂度
    引入适配器会增加额外的类和层次,可能使代码结构更复杂(过多适配器会导致逻辑混乱)。
  2. 转换开销
    适配器的转换逻辑可能引入轻微的性能损耗(通常可忽略)。

适用场景

  1. 接口不兼容的系统集成
    当需要使用已有类(如第三方库、 legacy 系统),但其接口与当前系统不兼容时,用适配器转换。
  2. 复用老旧代码
    对历史代码进行封装,使其适配新系统的接口,避免重写功能。
  3. 统一接口规范
    当多个类实现相似功能但接口不同时,用适配器统一为一个接口(如 Spring MVC 的 HandlerAdapter)。
  4. 测试驱动开发
    为测试模拟对象创建适配器,适配测试接口与实际接口。

总结

适配器模式是 “接口转换” 的利器,通过类继承或对象组合,使不兼容的接口能够协同工作。其核心价值在于复用现有功能解耦接口依赖,尤其适合系统集成、老旧代码复用等场景。在实际开发中,对象适配器因灵活性更高而更常用,但需注意避免过度使用导致系统臃肿

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10