设计模式之适配器模式(通俗易懂--代码辅助理解【Java版】)

文章目录

设计模式概述

创建型模式:工厂方法、抽象方法、建造者、原型、单例。

结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。

行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。

常用设计模式:

单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。

1、适配器模式

  • 适配器模式(Adapter Pattern )充当两个不兼容接口之间的桥梁,属于结构型设计模式。它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。

  • 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

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

  • 假设有一部手机,它只能接受typec口输入或输出;还有一个投影仪,投影仪只能接受vga口作为输入或输出;现在,我们需要实现手机屏幕投影到投影仪上,可以通过创建一个适配器来实现:

    • 目标接口:现有的投影仪只能接受vga口。
    • 适配者类:手机的输出口为typec口。
    • 适配器类:创建一个新的类,实现目标接口,并在内部使用适配者类来将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接。

3、优点

  • 促进了类之间的协同工作,即使它们没有直接的关联。
  • 提高了类的复用性。
  • 增加了类的透明度。
  • 提供了良好的灵活性。

4、缺点

  • 过度使用适配器可能导致系统结构混乱,难以理解和维护。
  • 在Java中,由于只能继承一个类,因此只能适配一个类,且目标类必须是抽象的

5、主要角色

  • 目标接口(Target):定义客户需要的接口。
  • 适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。
  • 适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。

6、代码示例

1)UML图

2)源代码

(1)定义一部手机,它有个typec口。

java 复制代码
/**
 * @author jstao
 * 定义一个手机Phone,它有一个Typec接口。
 * 
 */
public class Phone {
    public void typecPhone() {
        System.out.println("信息从Typec口的手机输出。");
    }
}

(2)定义一个vga接口。

java 复制代码
/**
 * @author jstao
 * 定义一个VGA接口。
 * 
 */
public interface Vga {
    void vgaInterface();
}

(3)实现一个适配器,适配器实现方式分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

1】类的适配器模式(通过继承特性来实现适配器功能)
java 复制代码
/**
 * 
 * 实现一个Type-c转VGA适配器,
 * 适配器实现方式有三种,这是第一种实现方式。
 * @author jstao
 *
 */
public class Typec2Vga1 extends Phone implements Vga{
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        typecPhone();
        System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
        System.out.println("信息已转换成VGA接口,显示屏可以对接。");
    }
}
2】对象的适配器模式(通过组合方式来实现适配器功能)
java 复制代码
/**
 * 
 * 实现一个Type-c转VGA适配器,
 * 适配器实现方式有三种,这是第二种实现方式。
 * @author jstao
 *
 */
public class Typec2Vga2 implements Vga{

    private Phone phone;
    
    public Typec2Vga2(Phone phone) {
        // TODO Auto-generated constructor stub
        this.phone = phone;
    }
    
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        if(phone != null) {
            phone.typecPhone();
            System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
            System.out.println("信息已转换成VGA接口,显示屏可以对接。");
        }
    }
}
3】接口的适配器模式(借助抽象类来实现适配器功能)

定义三个接口

java 复制代码
/**
 * 定义接口
 * @author jstao
 *
 */
public interface Target {
    
    void typec();
    void typec2vga();
    void typec2hdmi();
}

定义一个抽象类

java 复制代码
/**
 * 定义一个抽象类
 * @author jstao
 *
 */
public abstract class Adapter implements Target{

    public void typec() { }
    
    public void typec2vga() { }
    
    public void typec2hdmi() { }
}

实现一个vga适配器

java 复制代码
/**
 * 
 * 实现一个VGA适配器,同理还可以实现一个HDMI适配器
 * 适配器实现方式有三种,这是第三种实现方式。
 * @author jstao
 *
 */
public class VgaAdapter extends Adapter{
    
    public void typec() {
        System.out.println("信息从Typec口的手机输出。");
    }
    
    public void typec2vga() {
        System.out.println("接收到Type-c口信息,信息转换成VGA接口中...");
        System.out.println("信息已转换成VGA接口,显示屏可以对接。");
    }
}

(4)定义一个显示屏,用来测试上面实现的三个适配器。

java 复制代码
/**
 * 定义一个显示屏
 * 与适配器对接
 * @author jstao
 *
 */
public class Screen {
    public static void main(String[] args) {
        //第一种适配器用法
        System.out.println("-------------第一种适配器------------");
        Vga vga = new Typec2Vga1();
        vga.vgaInterface();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
        
        //第二种适配器用法
        System.out.println("-------------第二种适配器------------");
        Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone());
        typec2Vga1.vgaInterface();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
        
        //第三种适配器用法
        System.out.println("-------------第三种适配器------------");
        VgaAdapter vgaAdapter = new VgaAdapter();
        vgaAdapter.typec();
        vgaAdapter.typec2vga();//适配器将typec转换成vga
        System.out.println("显示屏对接适配器,手机成功投影到显示屏!");
    }
}

7、总结

  • 适配器模式在源码中的应用:

    • (1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。
    • (2)mybatis源码日志模块用到对象适配器模式。
  • 适配器模式将一个接口转为另外一个接口。它有三种实现方式:

    • (1)当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。

    • (2) 当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Typec2Vga2 类,持有原类的一个实例,在Typec2Vga2 类的方法中,调用实例的方法就行。

    • (3)当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可。

相关推荐
代码调试3 小时前
Springboot校园失物招领平台
java·spring boot
camellias_4 小时前
SpringBoot(二十三)SpringBoot集成JWT
java·spring boot·后端
tebukaopu1484 小时前
springboot如何获取控制层get和Post入参
java·spring boot·后端
昔我往昔4 小时前
SpringBoot 创建对象常见的几种方式
java·spring boot·后端
q567315234 小时前
用 PHP或Python加密字符串,用iOS解密
java·python·ios·缓存·php·命令模式
灭掉c与java4 小时前
第三章springboot数据访问
java·spring boot·后端
捕鲸叉4 小时前
怎样在软件设计中选择使用GOF设计模式
c++·设计模式
啊松同学4 小时前
【Java】设计模式——工厂模式
java·后端·设计模式
捕鲸叉4 小时前
C++设计模式和编程框架两种设计元素的比较与相互关系
开发语言·c++·设计模式
枫叶_v5 小时前
【SpringBoot】20 同步调用、异步调用、异步回调
java·spring boot·后端