适配器模式

目录

一、概念

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

相关推荐
WeiLai11121 小时前
面试基础--Redis 缓存穿透、缓存击穿、缓存雪崩深度解析
java·redis·分布式·后端·缓存·面试·架构
zctel1 小时前
java中小型公司面试预习资料(二):Redis
java·redis·面试
爱吃烤鸡翅的酸菜鱼2 小时前
Java【网络原理】(3)网络编程续
java·运维·服务器·网络
╰つ゛木槿5 小时前
Spring Boot 调用DeepSeek API的详细教程
java·spring boot·后端·deepseek
hhw1991126 小时前
c#面试题整理6
java·开发语言·c#
程序视点7 小时前
SpringBoot配置入门
java·spring boot·spring
Benaso8 小时前
Java,Golang,Rust 泛型的大体对比小记
java·golang·rust
程序员清风8 小时前
什么时候会考虑用联合索引?如果只有一个条件查就没有建联合索引的必要了么?
java·后端·面试
Seven978 小时前
【设计模式】掌握建造者模式:如何优雅地解决复杂对象创建难题?
java·后端·设计模式
自在如风。8 小时前
MyBatis-Plus 使用技巧
java·mybatis·mybatis-plus