• 【设计模式】 - 结构型模式 - 适配器模式


    前言

    结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。
    由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

    结构型模式分为以下 7 种:

    1. 代理模式
    2. 适配器模式
    3. 装饰者模式
    4. 桥接模式
    5. 外观模式
    6. 组合模式
    7. 享元模式

    适配器模式

    在这里插入图片描述

    适配器模式

    1. 概述

    如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插座转换器,转换器第1面插入当地的插座,第2面供我们充电,这样使得我们的插头在当地能使用。生活中这样的例子很多,手机充电器(将220v转换为5v的电压),读卡器等,其实就是使用到了适配器模式。
    在这里插入图片描述

    定义
    将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
    适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比后者高。

    2. 结构

    源(Adaptee):需要被适配的对象或类型,相当于插头。
    目标(Target):期待得到的目标,相当于插座。
    适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。

    3. 实现

    3.1 类适配器模式( 继承)–耦合度高

    适配器继承源,实现目标。

    从下面的结构图可以看出,Adaptee类并没有method2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,我们把Adaptee与Target衔接起来。Adapter与Adaptee是继承关系,这决定了这是一个类适配器模式。
    在这里插入图片描述

    代码实现

    源:

    public class Adaptee {
        public void method1(){
            System.out.println("method 1");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    目标:

    public interface Target {
        void method1();
        void method2();
    }
    
    • 1
    • 2
    • 3
    • 4

    适配器类:

    public class Adapter extends Adaptee implements Target {
        @Override
        public void method2() {
            System.out.println("method 2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试类:

    class AdapterTest {
        public static void main(String[] args) {
            Adapter adapter = new Adapter();
            adapter.method1();
            adapter.method2();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果:

    method 1
    method 2
    
    • 1
    • 2

    3.2 对象适配器模式(聚合)

    适配器聚合源,实现目标。

    从下面的结构图可以看出,Adaptee类并没有method2()方法,而客户端则期待这个方法。与类适配器模式一样,为使客户端能够使用Adaptee类,我们把Adaptee与Target衔接起来。但这里我们不继承Adaptee,而是把Adaptee封装进Adapter里。这里Adaptee与Adapter是组合关系。
    在这里插入图片描述

    代码实现

    Target和Adaptee和上面的类适配器一样,不再贴出。
    适配器类:

    public class Adapter implements Target {
    
        private Adaptee adaptee;
    
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        @Override
        public void method1() {
            adaptee.method1();
        }
    
        @Override
        public void method2() {
            System.out.println("method 2");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试类:

    class AdapterTest {
        public static void main(String[] args) {
            Adapter adapter = new Adapter(new Adaptee());
            adapter.method1();
            adapter.method2();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果:

    method 1
    method 2
    
    • 1
    • 2

    类适配器与对象适配器的区别

    类适配器使用的是继承的方式,直接继承了Adaptee,所以无法对Adaptee的子类进行适配。

    对象适配器使用的是组合的方式,所以Adaptee及其子孙类都可以被适配。另外,对象适配器对于增加一些新行为非常方便,而且新增加的行为同时适用于所有的源。

    基于组合/聚合优于继承的原则,使用对象适配器是更好的选择。但具体问题应该具体分析,某些情况可能使用类适配器会适合,最适合的才是最好的。

    4. 适配器模式的优缺点

    优点
    更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
    更好的扩展性:在实现适配器功能的时候,可以扩展自己源的行为(增加方法),从而自然地扩展系统的功能。
    缺点
    会导致系统紊乱:滥用适配器,会让系统变得非常零乱。例如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

    来源:https://blog.csdn.net/mrkohaku/article/details/79087688

  • 相关阅读:
    计算机竞赛 深度学习 YOLO 实现车牌识别算法
    解决Excel无法打开文件“xxx.xlsx“,因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式!匹配的问题
    干货!阿里「大型分布式技术手册」,站在巨人肩膀上学习架构
    【MyBatis】动态SQL
    Python21天学习挑战---day15 Python科学计算三剑客简介
    PC_多模块存储器
    10款自媒体人必备的免费工具,快速高效运营
    FPGA实现电机霍尔编码器模块
    express中间件(简介,流程,分类介绍)
    全志芯片Tina Linux 修改 UART 引脚、UART端口 (2)
  • 原文地址:https://blog.csdn.net/yzx3105/article/details/127981973