• 适配器模式


    一、适配器模式

    1、定义

    适配器模式(Adapter Pattern)又称作变压器模式,是指将一个类的接口变成客户端所期望的另一种接口,从而是原本因接口不匹配二导致无法在以下工作的两个类能够一起工作,属于结构型设计模式。

    适配器模式主要解决的是功能兼容问题。

    适配器字面意思就是使得一个东西能适合另一个东西的东西。

    2、结构

    (1)模式的结构

    主要角色如下:

    • 目标角色(ITarget):就是我们期望的接口。
    • 源角色(Adaptee):存在于系统中,是指内容满足客户需求(需要转换),但是接口不匹配的接口实例。
    • 适配器(Adapter):将 Adaptee 转换为目标角色 ITarget的类实例。

    (2)适配器模式有3种形式

    • 类适配器:原理就是通过继承来实现适配器的功能。Adapter实现 ITarget接口并继承 Adaptee。
    • 对象适配器:原理就是通过组合来实现适配器的功能。Adapter实现 ITarget接口,然后内部持有 Adaptee实例,最后在 ITarget接口中规定的方法内转换 Adaptee。
    • 接口适配器:适用于当目标接口的方法过多时,如果直接实现接口,则类会多出许多空实现的方法,显得很臃肿。所以,使用接口适配器就能只实现我们需要的接口方法,是目标更清晰。
      接口适配器的主要原理就是使用抽象类实现接口,并且空实现众多。

    3、优缺点

    优点:

    • 能提高类的透明性和复用,但现有的类复用不需要改变。
    • 适配器类和原角色类解耦,提高程序的扩展性。
    • 在很多业务场景中符合开闭原则。

    缺点:

    • 适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。
    • 增加底阿妈阅读难度,降低代码可读性。

    4、使用场景

    • 已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
    • 由于不同产品、不同厂家造成功能类似而接口不相同的情况下的解决方案。
    • 事后控制不如事中控制,事中控制不如事前控制。有时,只有碰到无法改变原有设计和代码的情况时,才会考虑适配器模式。

    5、在框架源码中使用

    • Spring AOP源码中的 AdvisorAdapter类。
    • Spring MVC源码中的 HandlerAdapter类。

    二、模式的通用实现

    以电源适配器来实例,我们民用电是 220V交流电,但是手机等电子产品使用的是 5V/12V等的直流电。所以充电时,需要适应电源适配器来进行转换。

    1、类适配器模式

    代码如下:

    public class ClassAdapterPattern {
    	public static void main(String[] args) {
    		PowerAdapter powerAdapter = new PowerAdapter();
    
    		int outputAC220V = powerAdapter.outputAC220V();
    		System.out.println(outputAC220V);
    		System.out.println("------------");
    		int output5V = powerAdapter.output5V();
    		System.out.println(output5V);
    	}
    }
    
    // 目标角色
    interface DC5 {
    	int output5V();
    }
    
    // 源角色
    class AC220 {
    	public int outputAC220V() {
    		int output = 220;
    		System.out.println("输出电压=" + output + "V");
    		return output;
    	}
    }
    
    // 适配器
    class PowerAdapter extends AC220 implements DC5{
    
    	@Override
    	public int output5V() {
    		int adapterInput = super.outputAC220V();
    		int adapterOutput = adapterInput / 44;
    		System.out.println("使用 Adapter输入AC=" + adapterInput + "V,输出 DC=" + adapterOutput + "V");
    		return adapterOutput;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述

    2、对象适配器模式

    代码如下:

    public class ObjectAdapterPattern {
    	public static void main(String[] args) {
    		PowerAdapter powerAdapter = new PowerAdapter(new AC220());
    
    		int output5V = powerAdapter.output5V();
    		System.out.println(output5V);
    	}
    }
    
    // 目标角色
    interface DC5 {
    	int output5V();
    }
    
    // 源角色
    class AC220 {
    	public int outputAC220V() {
    		int output = 220;
    		System.out.println("输出电压=" + output + "V");
    		return output;
    	}
    }
    
    // 适配器
    class PowerAdapter implements DC5{
    
    	private AC220 ac220;
    
    	public PowerAdapter(AC220 ac220) {
    		this.ac220 = ac220;
    	}
    
    	@Override
    	public int output5V() {
    		int adapterInput = ac220.outputAC220V();
    		int adapterOutput = adapterInput / 44;
    		System.out.println("使用 Adapter输入AC=" + adapterInput + "V,输出 DC=" + adapterOutput + "V");
    		return adapterOutput;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    3、接口适配器模式

    代码如下:

    public class InterfaceAdapterPattern {
    	public static void main(String[] args) {
    		PowerAdapter powerAdapter = new PowerAdapter(new AC220());
    
    		int output5V = powerAdapter.output5V();
    		System.out.println(output5V);
    		System.out.println("---------------");
    		int output12V = powerAdapter.output12V();
    		System.out.println(output12V);
    	}
    }
    
    // 目标角色
    interface DC {
    	int output5V();
    	int output12V();
    	int output24V();
    }
    
    // 源角色
    class AC220 {
    	public int outputAC220V() {
    		int output = 220;
    		System.out.println("输出电压=" + output + "V");
    		return output;
    	}
    }
    
    // 适配器
    class PowerAdapter implements DC{
    
    	private AC220 ac220;
    
    	public PowerAdapter(AC220 ac220) {
    		this.ac220 = ac220;
    	}
    
    	@Override
    	public int output5V() {
    		int adapterInput = ac220.outputAC220V();
    		int adapterOutput = adapterInput / 44;
    		System.out.println("使用 Adapter输入AC=" + adapterInput + "V,输出 DC=" + adapterOutput + "V");
    		return adapterOutput;
    	}
    
    	@Override
    	public int output12V() {
    		int adapterInput = ac220.outputAC220V();
    		int adapterOutput = adapterInput / 18;
    		System.out.println("使用 Adapter输入AC=" + adapterInput + "V,输出 DC=" + adapterOutput + "V");
    		return adapterOutput;
    	}
    
    	@Override
    	public int output24V() {
    		return 0;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    在这里插入图片描述

    – 求知若饥,虚心若愚。

  • 相关阅读:
    Python与CAD系列基础篇(四)创建矩形、倒角矩形、圆、椭圆
    [WPF] 假装可变字体
    06. Nginx进阶-Nginx代理服务
    倍思、南卡、漫步者开放式耳机好不好用? 硬核测评年度最强产品
    ftl和html的区别?
    【数据结构】搜索二叉树(C++实现)
    2023 ~【VUE+Xterm+Websocket】模拟SSH连接效果
    YOLOv8改进AFPN:改进用于目标检测的渐近特征金字塔网络AsymptoticFPN,加强非相邻层的直接交互,YOLO系列高效涨点
    46、Docker(数据卷:宿主机文件通过数据卷操作挂载到数据卷的容器数据)
    vue2 - 基于Export2Excel.js导出Excel案例(js-xlsx插件二次封装使用)
  • 原文地址:https://blog.csdn.net/qq_42402854/article/details/128174374