设计模式之适配器模式

56次阅读

共计 694 个字符,预计需要花费 2 分钟才能阅读完成。

原文链接:http://www.studyshare.cn/blog…

一、概念

适配器模式:作为两个不兼容接口之间的桥梁,可以将一个类的接口转换为我们希望的另外一个接口,使用适配器模式可以让原本由于接口不兼容而不能一起工作的那些类可以一起工作。如下图所示:

java 开发工具下载地址及安装教程大全,点这里。

更多深度技术文章,在这里。

二、应用场景

1、当调用双方都不太容易修改,但又为了复用现有组件,那么可以使用适配器模式进行转换。

2、在系统中接入第三方组件的时候,例如日志组件、支付组件等。可使用适配器模式。

三、案例

此处以接入一个第三方支付组件为例,详细说明适配器模式的使用方式。

假如现在需要开发一个支付功能,对外暴露一个接口,希望这个支付接口可以给其他系统提供多种支付功能(微信支付、支付宝支付、银联支付等),这是一种典型的适配器模式使用场景,第三方的支付组件(微信支付、支付宝支付、银联支付)通过适配器转换为提供出去的统一接口被调用。其他系统只需要调用暴露的统一接口即可。

代码实现:

1、支付宝、微信、银联支付组件

2、统一支付接口

  3、适配器类

  4、测试类

总结:在合适的场景合理使用适配器模式,上面适用场景 1 提出在调用双方都不方便修改的时候,例如为了适应自己的业务系统去要求支付宝修改这是不现实的。但是如果是本公司内部的两个或者多个业务子系统之间,能修改的情况尽可能修改,因为使用过多的适配器模式去实现无疑会增加系统的复杂性,不利于代码可读性,系统可维护性,此时设计人员需考虑对系统进行重构。

java 开发工具下载地址及安装教程大全,点这里。

更多深度技术文章,在这里。

原创文章,转载请注明出处。

正文完
 0

设计模式之适配器模式

55次阅读

共计 3580 个字符,预计需要花费 9 分钟才能阅读完成。

0x01. 定义和类型

  • 定义:将一个类的接口转换成客户期望的另一个接口,适配器模式让那些不兼容的类可以一起工作。
  • 类型:结构型

a. 类适配器模式

  • 类适配器模式:使用继承的方式去实现接口适配。
  • UML:

  • Java 实现
/**
 * 客户需要的接口
 */
public interface Target {void request();
}

/**
 * 被适配的类
 */
public class Adaptee {public void adapteeRequest () {System.out.println("被适配者的方法");
    }
}

/**
 * 适配器,继承了被适配的类,并且实现了 Target 定义的接口
 */
public class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        //todo...
        System.out.println("适配后 ----");
        super.adapteeRequest();
        //todo...
    }
}
  • 测试与应用
/**
 * 测试类
 */
public class Test {public static void main(String[] args) {Adaptee adaptee = new Adaptee();
        adaptee.adapteeRequest();

        Target adapterTarget = new Adapter();
        adapterTarget.request();}
}
  • 输出结果
 被适配者的方法
适配后 ----
被适配者的方法 

b. 对象适配器模式

  • 对象适配器模式:使用组合的方式去实现接口适配
  • UML

  • Java 实现
/**
 * 客户端应用放使用的接口
 */
public interface Target {void request();
}

/**
 * 被适配的类
 */
public class Adaptee {public void adapteeRequest () {System.out.println("被适配者的方法");
    }
}

/**
 * 适配器模式
 */
public class Adapter implements Target {

    /**
     * 组合了被适配的类,这里可以通过 set 方式注入
     */
    private Adaptee adaptee = new Adaptee();

    @Override
    public void request() {
        //todo...
        System.out.println("适配后 ----");
        adaptee.adapteeRequest();
        //todo...
    }
}
  • 应用与测试类
/**
 * 应用测试类
 */
public class Test {public static void main(String[] args) {Adaptee adaptee = new Adaptee();
        adaptee.adapteeRequest();

        Target adapterTarget = new Adapter();
        adapterTarget.request();}
}
  • 输入结果
 被适配者的方法
适配后 ----
被适配者的方法 

c. 角色介绍

  • 从上面两种情况可以看出,适配器模式一共有三个角色

    • Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。
    • Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对 Adaptee 和 Target 进行适配。它是适配器模式的核心。
    • Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

0x02. 适用场景

  • 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
  • 创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作
  • 适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案。

0x03. 优点

  • 能提高类的透明性和复用,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,现有的类复用但不需要改变,而且提高了适配者的复用性,同一适配者类可以在多个不同的系统中复用。
  • 目标类和适配器类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构,提高程序扩展性。
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便的更换适配器,也可以在不修改原有代码的基础上,增加新的适配器,符合开闭原则。

0x04. 缺点

  • 适配器编写过程需要全面考虑,可能会增加系统的复杂性。
  • 一次最多只能适配一个适配者类,不能同时适配多个适配者。
  • 增加系统代码可读的难度。

0x05. 样例实现

笔记本的插头为三项电,而现有的插座是两项的,需要适配器来进行适配,下面分别进行两种方式的实现。

  • 通用代码
/**
 * 三项插座接口
 * @author Administrator
 *
 */
public interface ThreePlugIf {
    // 使用三项电流供电
    void powerWithThree();}

/**
 * 二项电插座
 */
public class GBTowPlug {
    // 使用二项电流供电
    public void powerWithTwo () {System.out.println("使用二项电流供电");
    }
}

/**
 * 笔记本类
 */
public class NoteBook {

    private ThreePlugIf plug;

    /**
     * 只接收使用三项电充电
     * @param plug
     */
    public NoteBook (ThreePlugIf plug) {this.plug = plug;}

    /**
     * 使用插座充电
     */
    public void charge () {plug.powerWithThree();
    }
}

a. 类适配器的实现

  • 具体 Java 代码
/**
 * 采用继承方式的插座适配器
 * @author Administrator
 */
public class TwoPlugAdapterExtends extends GBTowPlug implements ThreePlugIf {public void powerWithThree() {System.out.println("借助继承适配器");
        this.powerWithTwo();}
}
  • 测试与应用类
/**
 * 测试与应用类
 */
public class AdapterTest {public static void main(String[] args) {ThreePlugIf three = new TwoPlugAdapterExtends();
        NoteBook book = new NoteBook(three);
        book.charge();}
}
  • 输出结果
 借助继承适配器
使用二项电流供电 
  • 样例 UML 类图:

b. 对象适配器的实现

  • 具体 Java 代码
/**
 * 二项插座转三项插座的适配器
 */
public class TwoPlugAdapter implements ThreePlugIf {

    /**
    * 组合
    */
    private GBTowPlug plug;

    public TwoPlugAdapter (GBTowPlug plug) {this.plug = plug;}

    public void powerWithThree() {System.out.println("通过转化");
        plug.powerWithTwo();}
}
  • 测试与应用类
/**
 * 测试与应用类
 */
public class AdapterTest {public static void main(String[] args) {GBTowPlug two = new GBTowPlug();
        ThreePlugIf three = new TwoPlugAdapter(two);
        NoteBook book = new NoteBook(three);
        book.charge();}
}
  • 输出结果
 对象适配器 - 通过转化
使用二项电流供电 
  • 样例 UML 类图:

0x06. 相关设计模式

  • 适配器模式和外观模式

    • 对现有的类现存系统的封装
    • 外观:定义了新的接口,创建新的接口对现有接口的封装
    • 适配器:复用原有的接口,使两个已有的接口协同工作
    • 两种:适配的力度不同,外观针对的力度更大

0x07. 源码中的适配器

  • JDK: XmlAdapter
  • Spring AOP: AdvisorAdapter, MethodBeforeAdvice
  • Spring Data JPA: JpaVendorAdapter
  • Spring MVC: Handler Adacpter

0x08. 源码地址

  • 适配器模式 : https://github.com/sigmako/design-pattern/tree/master/adapter

0x09. 参考

  • 慕课网设计模式精讲 : https://coding.imooc.com/class/270.html
  • 设计模式:适配器模式 : https://www.cnblogs.com/songyaqi/p/4805820.html

正文完
 0