适配器模式

目录

一、概念

1、定义

2、涉及到的角色

二、类适配器

1、类图

2、代码示例

(1)水饺(源角色)

(2)烹饪(目的角色)

(3)食品适配器(适配器角色)

(4)测试类

三、对象适配器

1、类图

2、代码示例

(1)包子(新增源角色)

(2)适配器角色

(3)测试类

四、总结

1、适配器模式的优点

2、适配器模式的使用场景

五、适配器模式的具体应用

[1、InputStreamReader 和 OutputStreamWriter](#1、InputStreamReader 和 OutputStreamWriter)

(1)用途

(2)InputStreamReader使用示例代码(从文件读取内容)

(3)OutputStreamWriter使用示例(将内容写入到文件中)

2、SpringMVC框架HandlerAdapter的应用


一、概念

1、定义

适配器相当于一个包装器,将一个类的接口变换成客户端所期待的另一种接口,从而使无法在一起工作的两个类能够在一起工作。

2、涉及到的角色

(1)目标角色(Target):要转换成的目标接口。

(2)源角色(Adaptee):需要被转换成目标角色的源角色。

(3)适配器角色(Adapter):通过继承或类关联的方式,将源角色转换成目标角色。

水饺、馄饨、煮饭(cook)

二、类适配器

1、类图

2、代码示例

(1)水饺(源角色)

java 复制代码
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)烹饪(目的角色)

java 复制代码
package com.xiaobai.design_pattern.adapter;

/**
 * @Author 王天文
 * @Date 2025/1/8 20:54
 * @Description: 适配器模式-馄饨(目标角色)
 */
public interface Cook {

    void prepareMeal();
}

(3)食品适配器(适配器角色)

java 复制代码
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;
    }

    @Override
    public void prepareMeal() {
        super.makeShuiJiao();
        log.info("烹饪完成,食物是:{}", name);
    }
}

(4)测试类

java 复制代码
package com.xiaobai.design_pattern.adapter;

import org.junit.jupiter.api.Test;

/**
 * @Author 王天文
 * @Date 2025/1/8 20:58
 * @Description: 适配器模式-测试
 */
public class AdapterTest {

    @Test
    public void classAdapterTest() {
        Cook hunDun = new FoodClassAdapter("饺子");
        hunDun.prepareMeal();
    }
}

三、对象适配器

1、类图

2、代码示例

(1)包子(新增源角色)

java 复制代码
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)适配器角色

java 复制代码
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();
        }
    }

    @Override
    public 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)测试类

java 复制代码
    @Test
    public 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使用示例代码(从文件读取内容)

java 复制代码
    @Test
    public 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使用示例(将内容写入到文件中)

java 复制代码
    @Test
    public 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

相关推荐
我是人✓5 小时前
Java核心语法:作用域、循环与大数值处理
java·开发语言·后端
夜之眷属6 小时前
PriorityQueue:for-each 遍历和 poll 取出,顺序一样吗?
java·服务器·数据结构·后端·算法
蜗牛互联网6 小时前
Java标准HTTP调用多模态模型的票据抽取前置校验
java·人工智能·python·http
工具派6 小时前
Agent 不是玄学:用 Java 状态机思维理解 LangGraph
java·人工智能·python
十年Java程序媛7 小时前
String / StringBuilder / StringBuffer|别再乱用字符串拼接,底层原理一次讲透
java·spring boot·后端
傲世仙尊7 小时前
类和对象中-构造函数与析构函数把初始化清理自动化
java·运维·自动化
她的男孩7 小时前
权限通了、列表有数,一点分页就炸Forge Admin 用 COUNT(1) 扛住复杂待办
java·spring boot·mybatis
骑着蜗牛撵大象3277 小时前
豆包 Seed 驱动的记账智能体:从拍票抽取到月报生成的全链路落地记录
java·前端·javascript·结构化输出·豆包seed·多模态识别·记账系统
憧憬成为java架构高手的小白7 小时前
langchain4j手敲理解
java·langchain
10mAh8 小时前
【Java】ArrayList 遍历删除为什么报错?三种写法与漏删复现
java·开发语言·windows