笔记 笔记
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

EasT-Duan

Java 开发
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

购买兑换码请添加

添加时候请写好备注,否则无法通过。

  • 设计模式

    • 简介

    • 原则

    • UML

    • 创建型

    • 结构型

      • 适配器模式
        • 简介
        • 类适配器模式
          • 代码示例
          • 说明
        • 对象适配器模式
          • 代码实例
          • 说明
        • 接口适配器模式
          • 代码实例
          • SpringMVC 中的适配器模式使用
      • 桥接模式
      • 装饰者模式
      • 组合模式
      • 外观模式
      • 享元模式
      • 代理模式
    • 行为型

  • JVM 详解

  • Linux

  • Redis

  • 分布式锁

  • Shiro

  • Gradle

  • Java 进阶
  • 设计模式
  • 结构型
EasT-Duan
2023-11-15
目录

适配器模式

欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。

# 简介

适配器模式 (Adapter Pattern) 将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器 (Wrapper)

适配器模式属于结构型模式

主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

从用户的角度看不到被适配者,是解耦的,用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法,用户收到反馈结果,感觉只是和目标接口交互。

# 类适配器模式

# 代码示例

/**
 * 适配接口
 */
public interface IVoltage5V {
	int output5V();
}
1
2
3
4
5
6
/**
 * 被适配的类
 */
public class Voltage220V {
	// 输出220V的电压
	public int output220V() {
		int src = 220;
		System.out.println("电压=" + src + "伏");
		return src;
	}
}
1
2
3
4
5
6
7
8
9
10
11
package adapter.classadapter;

/**
 * 适配器类
 */
public class VoltageAdapter extends Voltage220V implements IVoltage5V {

	@Override
	public int output5V() {
		int src = output220V();
		src = src / 44;
		return src;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 手机
 */
public class Phone {
	/**
	 * 充电
	 * @param iVoltage5V	
	 */
	public void charging(IVoltage5V iVoltage5V) {
		if (iVoltage5V.output5V() == 5) {
			System.out.println("电压为5V, 可以充电~~");
		} else if (iVoltage5V.output5V() > 5) {
			System.out.println("电压大于5V, 不能充电~~");
		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 说明

Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点,因为这要求 dst 必须是接口,有一定局限性。

src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。

由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。

# 对象适配器模式

基本思路和类的适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类,而是持有 src 类的实例,以解决兼容性的问题。 即:持有 src 类,实现 dst 类接口,完成 src→dst 的适配。

根据 “合成复用原则”,在系统中尽量使用关联关系来替代继承关系。

对象适配器模式是适配器模式常用的一种。

# 代码实例

/**
 * 适配器类
 */
@AllArgsConstructor //提供一个全参构造
public class VoltageAdapter implements IVoltage5V {
	private Voltage220V voltage220v;

	@Override
	public int output5V() {
		int dst = 0;
		if (null != voltage220v) {
			// 获取220v电压
			int output220v = voltage220v.output220V();
			System.out.println("使用对象适配器,进行适配~~");
			dst = output220v / 44;
			System.out.println("适配完成,输出的电压为=" + dst);
		} else {
			throw new RuntimeException("没有电源接入");
		}
		return dst;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 客户端
 */
public class Client {

	public static void main(String[] args) {
		System.out.println(" === 类适配器模式 ====");
		Phone phone = new Phone();
		Voltage220V voltage220v = new Voltage220V();
		VoltageAdapter voltageAdapter = new VoltageAdapter(voltage220v);
		phone.charging(voltageAdapter);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 说明

对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。 根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst 必须是接口

这种方式使用成本更低,更灵活。

# 接口适配器模式

一些书籍称为:适配器模式 (Default Adapter Pattern) 或缺省适配器模式。

当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。

适用于一个接口不想使用其所有的方法的情况。

# 代码实例

public interface Interface4 {
	void m1();

	void m2();

	void m3();

	void m4();
}
1
2
3
4
5
6
7
8
9
/**
 * 在 AbsAdapter 我们将 Interface4 的方法进行默认实现
 */
public abstract class AbsAdapter implements Interface4 {

	@Override
	public void m1() {

	}

	@Override
	public void m2() {

	}

	@Override
	public void m3() {

	}

	@Override
	public void m4() {

	}
}
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
/**
 * 客户端
 */
public class Client {
	public static void main(String[] args) {
		AbsAdapter adapter = new AbsAdapter() {
            // 只想用到m1方法
			@Override
			public void m1() {
				System.out.println("我重写了M1方法");
			}
		};
		adapter.m1();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# SpringMVC 中的适配器模式使用

  • Spring 定义了一个适配接口,使得每一种 Controller 有一种对应的适配器实现类。
  • 适配器代替 Controller 执行相应的方法。
  • 扩展 Controller 时,只需要增加一个适配器类就完成了 SpringMVC 的扩展了。
// DispatchServlet.doDispatch()
// 通过request中的请来映射Controller
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
    noHandlerFound(processedRequest, response);
    return;
}

// 通过遍历找到Controller对应的适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
1
2
3
4
5
6
7
8
9
10

手写 SpringMVC 通过适配器设计模式获取到对应的 Controller 的源码

/**
 * 定义一个Adapter接口 
 */
public interface HandlerAdapter {
	public boolean supports(Object handler);

	public void handle(Object handler);
}
//多种适配器类
class SimpleHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((SimpleController) handler).doSimplerHandler();
	}

	public boolean supports(Object handler) {
		return (handler instanceof SimpleController);
	}
}
class HttpHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((HttpController) handler).doHttpHandler();
	}

	public boolean supports(Object handler) {
		return (handler instanceof HttpController);
	}
}
class AnnotationHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((AnnotationController) handler).doAnnotationHandler();
	}

	public boolean supports(Object handler) {
		return (handler instanceof AnnotationController);
	}
}
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
//多种Controller实现  
public interface Controller {

}
class HttpController implements Controller {
	public void doHttpHandler() {
		System.out.println("http...");
	}
}

class SimpleController implements Controller {
	public void doSimplerHandler() {
		System.out.println("simple...");
	}
}

class AnnotationController implements Controller {
	public void doAnnotationHandler() {
		System.out.println("annotation...");
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * 用来模拟Springmvc中DispatchServlet的适配器模式,DispatchServlet中的核心代码为doDispatch,
 * 如果以后有新增的Controller,只需要新增一个适配器即可,做到了和代码的解耦
 */
public class DispatchServlet {

	public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();

	public DispatchServlet() {
		handlerAdapters.add(new AnnotationHandlerAdapter());
		handlerAdapters.add(new HttpHandlerAdapter());
		handlerAdapters.add(new SimpleHandlerAdapter());
	}

	public void doDispatch() {
		// 此处模拟SpringMVC从request取handler的对象,
		// 适配器可以获取到希望的Controller
		HttpController controller = new HttpController();
		// AnnotationController controller = new AnnotationController();
		// SimpleController controller = new SimpleController();
		// 得到对应适配器
		HandlerAdapter adapter = getHandler(controller);
		// 通过适配器执行对应的controller对应方法
		adapter.handle(controller);
	}

	public HandlerAdapter getHandler(Controller controller) {
		// 遍历:根据得到的controller(handler), 返回对应适配器
		for (HandlerAdapter adapter : handlerAdapters) {
			if (adapter.supports(controller)) {
				return adapter;
			}
		}
		return null;
	}

	public static void main(String[] args) {
		new DispatchServlet().doDispatch(); // http...
	}
}
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
#设计模式
上次更新: 2025/04/12, 07:54:33
建造者模式
桥接模式

← 建造者模式 桥接模式→

最近更新
01
Reactor 核心
02-24
02
前置条件
10-30
03
计算机网络
09-13
更多文章>
Theme by Vdoing | Copyright © 2019-2025 powered by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式