结构型模式——适配器模式(三)

2019-05-22  本文已影响0人  最后的轻语_dd43

该项目源码地址:https://github.com/ggb2312/Code/tree/master/java-basic/design-pattern
(设计模式相关代码与笔记)

1. 定义

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

2. 适用场景

3. 适配器类图与角色

3.1 适配器类型

适配器类型有两种类型实现,一种是类适配器,一种是对象适配器。

(1)类适配器

通过类继承实现的。

类适配器

让Adapter继承Adaptee类,Client在使用Target的request()接口(实际上是调用Adapter的request()方法)时,间接调用adapteeRequest()方法。

(2)对象适配器

符合组合复用原则,使用委托机制。

对象适配器

对比着类适配器理解。在Adapter内部创建Adaptee对象,Client在使用Target的request()接口(实际上是调用Adapter的request()方法)时,间接调用adapteeRequest()方法。

3.2 角色

由图可知适配器模式包含一下三个角色:

4. 相关设计模式

适配器模式和外观模式

5. 模式实例

5.1 类适配器

Adaptee 有一个被适配器类:

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

Target 这个是目标方法的接口:

public interface Target {
    void request();
}

ConcreteTarget 这个是目标方法的实现:

/** 具体的实现类 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("ConcreteTarget目标方法");
    }
}

Adapter 而这个就是适配类:继承于被适配类,实现目标方法的接口:

public class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        super.adapteeRequest();
    }
}

Client 我们来进行测试一下:

public class Test {
    public static void main(String[]args){
        Target target = new ConcreteTarget();
        target.request();

        /** 现在,我们就来通过适配器类来进行实现 */
        Target adapterTarget = new Adapter();
        adapterTarget.request();
    }
}

测试结果:

测试结果

此时的类图:

类适配器类图

5.2 对象适配器

有一个目标接口:

public interface Target {
    void request();
}

有一个具体的目标类:

/** 具体的实现类 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("ConcreteTarget目标方法");
    }
}

以及被适配的类:

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

适配类和上面的有一些不同,这里被适配类不是继承过来的,而是作为属性组合到里面来,然后通过对象来调用被适配类里面的方法:

public class Adapter implements Target {

    private Adaptee adaptee = new Adaptee();

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

测试:

public class Test {
    public static void main(String[]args){
        Target target = new ConcreteTarget();
        target.request();

        /** 现在,我们就来通过适配器类来进行实现 */
        Target adapterTarget = new Adapter();
        adapterTarget.request();
    }
}

测试结果:

测试结果

此时类图:

对象适配类图

5.3 适配器demo

简单的抽象一个场景:手机充电需要将220V的交流电转化为手机锂电池需要的5V直流电,我们的demo就是写一个电源适配器,将 AC220v ——> DC5V

首先有一个被适配的类:220V的类

public class AC220 {
    public int outputAC220V() {
        int output = 220;
        System.out.println("输出220V的交流电"+output+"V");
        return output;
    }
}

我们有一个目标方法的接口:转为5V的直流电

public interface DC5 {
    int outputDC5V();
}

这个就是适配类(使用对象适配):

public class PowerAdapter implements DC5 {

    private AC220 ac220 = new AC220();

    @Override
    public int outputDC5V() {
        int adapterInput = ac220.outputAC220V();
        /** 变压器 */
        int adapterOutput = adapterInput / 44;
        System.out.println("通过PowerAdapter电源适配器输入AC"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
        return adapterOutput;
    }
}

测试:

public class Test {
    public static void main(String[]args){
        DC5 dc5 = new PowerAdapter();
        dc5.outputDC5V();
    }
}

测试结果:

测试结果

6. 优缺点

优点:

缺点:

7. 扩展-JDK1.7以及框架源码中的适配器模式

javax.xml.bind.annotation.adapters.XmlAdapter

org.springframework.aop.framework.adapter.AdvisorAdapter、MethodBeforeAdviceAdapter

org.springframework.orm.jpa.JpaVendorAdapter

org.springframework.web.servlet.HandlerAdapter、org.springframework.web.servlet.DispatcherServlet、org.springframework.web.servlet.mvc.Controller

上一篇 下一篇

猜你喜欢

热点阅读