目录
一、概念
1、定义
2、涉及到的角色
二、类适配器
1、类图
2、代码示例
(1)水饺(源角色)
(2)烹饪(目的角色)
(3)食品适配器(适配器角色)
(4)测试类
三、对象适配器
1、类图
2、代码示例
(1)包子(新增源角色)
(2)适配器角色
(3)测试类
四、总结
1、适配器模式的优点
2、适配器模式的使用场景
五、适配器模式的具体应用
1、InputStreamReader 和 OutputStreamWriter
(1)用途
(2)InputStreamReader使用示例代码(从文件读取内容)
(3)OutputStreamWriter使用示例(将内容写入到文件中)
2、SpringMVC框架HandlerAdapter的应用
一、概念
1、定义
适配器相当于一个包装器,将一个类的接口变换成客户端所期待的另一种接口,从而使无法在一起工作的两个类能够在一起工作。
2、涉及到的角色
(1)目标角色(Target):要转换成的目标接口。
(2)源角色(Adaptee):需要被转换成目标角色的源角色。
(3)适配器角色(Adapter):通过继承或类关联的方式,将源角色转换成目标角色。
水饺、馄饨、煮饭(cook)
二、类适配器
1、类图
2、代码示例
(1)水饺(源角色)
package com.xiaobai.design_pattern.adapter;import lombok.extern.slf4j.Slf4j;/*** @Author 王天文* @Date 2025/1/8 20:52* @Description: 适配器模式-水饺(源角色)*/
@Slf4j
public class ShuiJiao {public void makeShuiJiao() {log.info("调制菜陷");log.info("擀面皮");log.info("包饺子");}
}
(2)烹饪(目的角色)
package com.xiaobai.design_pattern.adapter;/*** @Author 王天文* @Date 2025/1/8 20:54* @Description: 适配器模式-馄饨(目标角色)*/
public interface Cook {void prepareMeal();
}
(3)食品适配器(适配器角色)
package com.xiaobai.design_pattern.adapter;import lombok.extern.slf4j.Slf4j;/*** @Author 王天文* @Date 2025/1/8 20:55* @Description: 适配器模式-适配器角色(食品适配器)*/
@Slf4j
public class FoodClassAdapter extends ShuiJiao implements Cook {private String name;public FoodClassAdapter(String name) {this.name = name;}@Overridepublic void prepareMeal() {super.makeShuiJiao();log.info("烹饪完成,食物是:{}", name);}
}
(4)测试类
package com.xiaobai.design_pattern.adapter;import org.junit.jupiter.api.Test;/*** @Author 王天文* @Date 2025/1/8 20:58* @Description: 适配器模式-测试*/
public class AdapterTest {@Testpublic void classAdapterTest() {Cook hunDun = new FoodClassAdapter("饺子");hunDun.prepareMeal();}
}
三、对象适配器
1、类图
2、代码示例
(1)包子(新增源角色)
package com.xiaobai.design_pattern.adapter;import lombok.extern.slf4j.Slf4j;/*** @Author 王天文* @Date 2025/1/26 16:46* @Description:*/
@Slf4j
public class BaoZi {public void makeBaoZi() {log.info("开始包包子");log.info("调制菜陷");log.info("擀面皮");log.info("包包子");}
}
(2)适配器角色
package com.xiaobai.design_pattern.adapter;import lombok.extern.slf4j.Slf4j;/*** @Author 王天文* @Date 2025/1/26 22:15* @Description:*/
@Slf4j
public class FoodObjectAdapter implements Cook {private BaoZi baoZi;private ShuiJiao shuiJiao;private String name;public FoodObjectAdapter(String name) {this.name = name;if ("包子".equals(name)) {this.baoZi = new BaoZi();}if ("水饺".equals(name)) {this.shuiJiao = new ShuiJiao();}}@Overridepublic void prepareMeal() {boolean flag = false;if ("包子".equals(name)) {flag = true;this.baoZi.makeBaoZi();}if ("水饺".equals(this.name)) {flag = true;this.shuiJiao.makeShuiJiao();}if (flag) {log.info("烹饪完成,食物是:{}", name);} else {log.error("无法烹饪!");}}
}
(3)测试类
@Testpublic void objectAdapterTest() {Cook cook1 = new FoodObjectAdapter("水饺");cook1.prepareMeal();Cook cook2 = new FoodObjectAdapter("包子");cook2.prepareMeal();}
四、总结
1、适配器模式的优点
(1)可以让两个没有任何关系的类在一起运行;
(2)提高类的复用性;
(3)增强代码的灵活性
2、适配器模式的使用场景
存在一个不符合系统中接口的类,可以使用适配器模式将不符合系统接口的类转换成符合系统接口的类。
五、适配器模式的具体应用
1、InputStreamReader
和 OutputStreamWriter
(1)用途
InputStreamReader可以将字节输入流转换为字符输入流,它可以读取字节输入流,并使用指定的字符集将字节解码为字符。
OutStreamReader使用指定的字符集将写入的字符编码成字节,然后写入底层的字节输出流。
(2)InputStreamReader使用示例代码(从文件读取内容)
@Testpublic void testReadText() {String textContent = "";try (FileInputStream fileInputStream = new FileInputStream("D:\\temp\\daifu\\A0351__20250124_.txt");InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) {char[] cbuf = new char[20];int len = 0;while ((len = inputStreamReader.read(cbuf)) != -1) {textContent += new String(cbuf, 0, len);}} catch (Exception e) {e.printStackTrace();}log.info("文件内容:" + textContent);}
(3)OutputStreamWriter使用示例(将内容写入到文件中)
@Testpublic void testWriteText() {// 创建文本文件File tempFile = new File("D:\\temp\\outputStreamWriter\\测试.txt");try {tempFile.createNewFile();} catch (IOException e) {e.printStackTrace();}String textContent = "";for (int i = 10; i < 20; i++) {textContent = textContent + "测试数据" + i + "\r\n";}try(FileOutputStream fileOutputStream = new FileOutputStream(tempFile);OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, Charset.forName("UTF-8"))) {outputStreamWriter.write(textContent);// 刷新缓冲区,缓冲区中的数据会被立即写出,确保数据的及时传输和存储outputStreamWriter.flush();} catch (Exception e) {e.printStackTrace();}}
2、SpringMVC框架HandlerAdapter的应用
(1)HandlerMapping根据请求路径获取对应的处理器(handler),根据处理器判断使用的适配器模式,根据适配器和方法执行目标方法。
(2)适配器源码解析可参考:
Yngz_Miao-【Spring MVC】HandlerAdapter初始化详解(超详细过程源码分析)
唐叭叭-浅谈HandlerAdapter