ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式之适配器模式

2022-01-19 23:33:07  阅读:155  来源: 互联网

标签:适配 适配器 接口 adaptee void 模式 设计模式 public


1、简介

1.1 定义

适配器模式 Adapter:将一个类的接口转换为客户端希望的另外一个接口,使原本因为接口不匹配(或者不兼容)而无法在一起工作的两个类能够在一起工作。像是 Mac 的转换头、插座、数据线等,都是适配器模式的体现

1.2 结构

适配器模式(Adapter)包含以下主要角色

  • 目标(Target)接口:当前系统业务所期待的接口,可以是抽象类或接口
  • 适配者(Adaptee)类:被访问和适配的现存组件中的组件接口
  • 适配器(Adapter):转换器,通过继承或引用适配者的对象,把适配者接口转换为目标接口,让客户按照目标接口的格式访问适配者

1.3 优缺点

优点:

  • 客户端通过适配器可以透明的调用目标接口
  • 复用了现有的类,不需要修改原来的代码而重用现有的适配者类
  • 将很多目标类和适配者解耦,解决了目标类和适配者类接口不一致的问题

缺点:

  • 对于类适配器来讲,更换适配器的实现过程比较复杂,可能增加系统复杂性
  • 用的多了会使系统代码变得凌乱

1.4 分类

适配器模式分为类结构性模式和对象结构型模式两种,类结构型模式用的较少些,并且类之间的耦合度比对象结构型模式更高一些

1.4.1 类的适配器模式(继承实现)

类适配器模式——适配器继承自己实现的类(一般多重继承)

Adapter 与 Adaptee 是继承关系

  • 用一个具体的 Adapter 类和 Target 进行匹配。当我们想要一个匹配一个类以及所有它的子类时,类 Adapter 将无法胜任工作
  • 使 Adapter 可以重定义 Adaptee 的部分行为
  • 仅仅引入一个对象,并不需要额外的指针以简介取得 adaptee

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5Ts7OVz-1642605844230)(/var/folders/fj/225wqvz13hq0tflcnkl4y_v40000gn/T/abnerworks.Typora/image-20220119221146727.png)]

1.4.2 对象适配器(对象组合实现)

Adapter 和 Adaptee 是委托关系

  • 允许一个 Adapter 与多个 Adaptee 同时工作,Adapter 也可以一次给所有的 Adapter 添加功能
  • 使用重定义 Adaptee 的行为比较困难

无论哪种适配器都是为了在不改变原有系统的基础上,提供新的接口服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxIiJI0x-1642605844231)(/var/folders/fj/225wqvz13hq0tflcnkl4y_v40000gn/T/abnerworks.Typora/image-20220119221212146.png)]

2、代码实现

2.1 类适配器

// 目标接口
public interface Target {
    void request();
}

// 适配者类
public class Adaptee {
    public void specificRequest(){
        System.out.println("适配者被调用");
    }
}

// 类适配器
public Adapter extends Adaptee implements Target {
    
    @Override
    public void request(){
        specificRequest();
    }
}

// 客户端
public class ClassAdapterTest {
    public static void main(String[] args) {
        Target target = new ClassAdapter();
        target.request();
    }
}

// 运行结果如下:
// 适配者被调用

2.2 对象适配器

// 目标接口
public interface Target {
    void request();
}

// 适配者
public class Adaptee {
    void specificRequest() {
        System.out.println("适配者被调用了");
    }
}

// 对象适配器
public class ObjectAdapter implements Target {

    private Adaptee adaptee;

    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }

}

// 对象适配器测试
public class ObjectAdapterTest {

    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        ObjectAdapter objectAdapter = new ObjectAdapter(adaptee);
        objectAdapter.request();
    }

}

3、应用场景

  • 使用第三方提供的组件,但组件接口与自己要求的接口定义不同
  • 以前开发的系统中存在满足新系统功能需求的类,但接口与新系统接口不一致

4、模式扩展

适配器模式(Adapter)可以扩展为双向适配器模式,可以把适配者接口转为目标接口,也可以把目标接口转为适配者接口,如下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zycetJmJ-1642605844231)(/var/folders/fj/225wqvz13hq0tflcnkl4y_v40000gn/T/abnerworks.Typora/image-20220119225805884.png)]

代码实现:

/**
 * 目标接口
 */
public interface TwoWayTarget {
    
    void request();
    
}

/**
 * 目标实现
 */
public class TargetRealize implements TwoWayTarget {
    @Override
    public void request() {
        System.out.println("目标代码被调用");
    }
}


/**
 * 适配者接口
 */
public interface TwoWayAdaptee {

    void specificRequest();

}

/**
 * 适配者实现
 */
public class AdapteeRealize implements TwoWayAdaptee{
    @Override
    public void specificRequest() {
        System.out.println("适配者代码被调用");
    }
}

/**
 * 双向适配器
 */
public class TwoWayAdapter implements TwoWayAdaptee, TwoWayTarget{

    private TwoWayTarget target;

    private TwoWayAdaptee adaptee;

    public TwoWayAdapter(TwoWayAdaptee adaptee) {
        this.adaptee = adaptee;
    }

    public TwoWayAdapter(TwoWayTarget target) {
        this.target = target;
    }

    @Override
    public void specificRequest() {
        target.request();
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

/**
 * 双向适配器客户端
 */
public class TwoWayAdapterTest {

    public static void main(String[] args) {
        TwoWayAdaptee adaptee = new AdapteeRealize();
        TwoWayTarget target = new TwoWayAdapter(adaptee);
        target.request();
        System.out.println("~~~~~~~~~~~~~");
        target = new TargetRealize();
        adaptee = new TwoWayAdapter(target);
        adaptee.specificRequest();
    }

}

标签:适配,适配器,接口,adaptee,void,模式,设计模式,public
来源: https://blog.csdn.net/qq_53316135/article/details/122591819

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有