适配器模式

目录

一、概念

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、InputStreamReaderOutputStreamWriter

(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

相关推荐
架构师沉默1 小时前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
Java中文社群3 小时前
重要:Java25正式发布(长期支持版)!
java·后端·面试
每天进步一点_JL4 小时前
JVM 类加载:双亲委派机制
java·后端
用户298698530144 小时前
Java HTML 转 Word 完整指南
java·后端
渣哥4 小时前
原来公平锁和非公平锁差别这么大
java
渣哥5 小时前
99% 的人没搞懂:Semaphore 到底是干啥的?
java
J2K5 小时前
JDK都25了,你还没用过ZGC?那真得补补课了
java·jvm·后端
kfyty7255 小时前
不依赖第三方,不销毁重建,loveqq 框架如何原生实现动态线程池?
java·架构
isysc16 小时前
面了一个校招生,竟然说我是老古董
java·后端·面试
道可到9 小时前
Java 反射现代实践速查表(JDK 11+/17+)
java