设计模式 06 适配器模式

适配器模式(Adapter Pattern)属于结构型模式

概述

结构型模式关注如何将现有的类或对象组织在一起形成更加强大的结构。

在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。但日常使用中是往往需要连接网口上网的,这时想到的第一个解决方案,就是去买一个转接头 或者扩展坞 。它们可以将 type-c 或者 usb-a 转换为其他类型的接口供我们使用,实际上这就是一种适配器模式。

我们常用的充电头,为什么叫电源适配器 呢?传统的供电是 220V 交流电,但是手机可能只需要 5V 的电压进行充电,所以虽然现在有电,但是不能直接充。也不可能让电力公司专门为我们提供一个 5V 的直流电使用,这时电源适配器就开始发挥作用了。比如苹果的祖传 5V1A 充电头,实际上就是将 220V 交流电转换为 5V 的直流电进行传输。这样就相当于在 220V 交流电和手机之间,做了一个适配器的角色。

适配器模式分为类适配器 和对象适配器。

代码实现

这里以电脑需要转接器连接网线上网为例:

类适配器

1、定义电脑

java 复制代码
/**
 * 电脑
 * <p>想上网,需要插网线
 */
public class Computer {

    /**
     * 电脑需要连接上转换器才可以上网
     *
     * @param adapter 转接器
     */
    public void connect(NetToUsb adapter) {
        
        // 上网的具体实现,找一个转接头
        adapter.connectNetLine();
    }
}

2、定义网线

java 复制代码
/**
 * 网线
 */
public class NetLine {

    /**
     * 上网
     */
    public void online(){
        System.out.println("连接网线上网");
    }
}

3、定义 usb 转网口转接器

java 复制代码
/**
 * 转接器
 */
public interface NetToUsb {

    /**
     * 处理请求,usb -> 网线
     */
    void connectNetLine();
}

4、定义类适配器

java 复制代码
/**
 * 类适配器
 */
public class ClassAdapter extends NetLine implements NetToUsb {

    @Override
    public void connectNetLine() {
        // 可以上网了
        super.online();
    }
}

5、使用适配器连接网线上网

java 复制代码
// 电脑
Computer computer = new Computer();
// 转接器已经插上网线
ClassAdapter adapter = new ClassAdapter();
// 电脑连接转接器,成功上网
computer.connect(adapter);

这种实现方式需要占用一个继承位。如果此时 NetToUsb 不是接口而是抽象类的话,由于 Java 不支持多继承,就无法实现了。同时根据合成复用原则,应该更多的通过合成的方式去实现功能。

所以来看看第二种,也是用的比较多的一种模式:对象适配器。

对象适配器

4、定义对象适配器

java 复制代码
/**
 * 对象适配器
 */
public class ObjectAdapter implements NetToUsb {

    /**
     * 网线
     */
    private NetLine netLine;

    public ObjectAdapter(NetLine netLine) {
        this.netLine = netLine;
    }

    @Override
    public void connectNetLine() {
        // 可以上网了
        netLine.online();
    }
}

5、使用适配器连接网线上网

java 复制代码
/**
 * 测试示例
 */
public class ObjectAdapterTest {

    @Test
    public void test() {
        // 电脑
        Computer computer = new Computer();
        // 网线
        NetLine netLine = new NetLine();
        // 转接器插上网线
        ObjectAdapter adapter = new ObjectAdapter(netLine);
        // 电脑连接转接器,成功上网
        computer.connect(adapter);
    }

}

这样的方式不会占用继承位,且满足合成复用原则,耦合度更低,也更加灵活,推荐使用。

优缺点

优点

1、可以让任何两个没有关联的类一起运行。

2、提高了类的复用。

3、增加了类的透明度。

4、灵活性好。

缺点

1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

2、由于 Java 至多继承一个类,所以至多只能适配一个类,而且目标类必须是抽象类。

使用场景

有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

注意事项

适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。


参考

https://www.bilibili.com/video/BV1mc411h719?p=7&vd_source=299f4bc123b19e7d6f66fefd8f124a03

相关推荐
范中勤14 小时前
技术文档:模型工厂 `llm_provider` / `llm_use` 分层设计
设计模式·langchain·架构设计·模型工厂·llm_provider
浅尝辄止;16 小时前
设计模式在HIS/LIS医疗系统中的完整实践指南(C#版)
开发语言·设计模式·c#
范中勤16 小时前
适配器模式(Adapter Pattern):原理、场景与 LLM 多厂商工程落地
设计模式·架构·langchain·适配器模式·多厂商
408高手1 天前
23种设计模式
设计模式
yuehuaxin011 天前
上海贝岭 BL6523GX(D78) 单相计量芯片开发笔记:引脚定义、寄存器配置与校表流程
嵌入式硬件·智能家居·适配器模式·智能硬件
沫璃染墨1 天前
《Linux工程实践篇(二):线程池实战——从线程安全单例到完整源码实现》
linux·开发语言·c++·单例模式·设计模式·系统架构
sarasuki2 天前
MCP 为什么是一个协议而不是一个框架呢?
设计模式·agent·mcp
geovindu2 天前
rust: Borg Pattern(续)
开发语言·后端·设计模式·rust·博格模式
染指11102 天前
140.Agent-多Agent框架-Agent执行Skills流程
数据库·人工智能·设计模式·langchain·agents
sarasuki3 天前
Agent 是怎么做错误处理的呢?
人工智能·设计模式·agent