GOF23-适配器模式

适配器模式(wrapper包装者模式):将一个接口转换成用户所需要的接口,使相互不兼容的接口一起工作。

例子:笔记本、笔记本电源适配器、交流电。  在各个国家的交流电有些是不相同的,如220V、110V,而笔记本电脑充电电压基本为20V(以我的Y7000为例),是不能直接接入充电的,因此笔记本都配置了一个电源适配器。这就用到了适配器模式

适配器模式中常用的角色

  • Target(目标角色,笔记本20V直流电):目标接口或者类  DC20Tage及其实现类
  • Adapter(适配器,电源适配器):将原角色适配为目标角色 DC20Adapter及其实现类
  • Adaptee(原角色,110V,220V交流电):需要适配的类 ACAdaptee及其实现类

一、UML类图

GOF23-适配器模式_第1张图片

二、代码

1.Target 目标

package adapter;

public interface DC20Taget {
    int outputDC();
}
package adapter;

/**
 * 目标为生产出笔记本所需要的电
 */
public class LoptopTaget implements DC20Taget {
    private int voltage;

    public LoptopTaget(int voltage) {
        this.voltage = voltage;
    }

    public int outputDC() {
        return voltage;
    }
}

2.Adaptee 原代码

package adapter;

public interface ACAdaptee {
    int outputAC();
}
package adapter;

/**
 * 需要适配的110V电源
 */
public class AmericaACAdaptee implements ACAdaptee {
    private final int voltage = 110;
    public int outputAC() {
        return voltage;
    }
}
package adapter;

/**
 * 需要适配的220V电源
 */
public class ChinaACAdaptee implements ACAdaptee {
    private final int voltage = 220;
    public int outputAC() {
        return voltage;
    }
}

3.Adapter 适配器

package adapter;

public interface DC20Adapter {
    boolean support(ACAdaptee ac);
    DC20Taget outputDC20();
}
package adapter;

/**
 * 110V电源适配器,转换为笔记本需要的电源并且返回
 */
public class AmericaPowerAdapter implements DC20Adapter {
    private final int voltage = 110;
    private ACAdaptee ac;
    public boolean support(ACAdaptee ac) {
        boolean flag = voltage == ac.outputAC();
        this.ac = flag ? ac: this.ac ;
        return flag;
    }

    public DC20Taget outputDC20() {
        int inputVoltage = ac.outputAC();
        int out = ((Double)(inputVoltage/5.5)).intValue();
        System.out.println("使用AmericaPowerAdapter,输入电压"+inputVoltage+"输出电压"+out);
        DC20Taget dc20 = new LoptopTaget(out);
        return dc20;
    }
}
package adapter;

/**
 * 220V电源适配器,返回笔记本所需要的电源
 */
public class ChinaPowerAdapter implements DC20Adapter {
    private final int voltage = 220;
    private ACAdaptee ac;
    public boolean support(ACAdaptee ac) {
        boolean flag = voltage == ac.outputAC();
        this.ac = flag ? ac: this.ac;
        return flag;
    }

    public DC20Taget outputDC20() {
        int inputVoltage = ac.outputAC();
        int out = inputVoltage/11;
        System.out.println("使用ChinaPowerAdapter,输入电压"+inputVoltage+"输出电压"+out);
        DC20Taget dc20 = new LoptopTaget(out);
        return dc20;
    }
}

4.测试代码

package adapter;

import java.util.LinkedList;
import java.util.List;

public class Client {
    //需要的适配器组
    private List adapters = new LinkedList();
    public Client(){
        this.adapters.add(new ChinaPowerAdapter());
        this.adapters.add(new AmericaPowerAdapter());
    }

    //返回所需要的适配器
    public DC20Adapter getAdapter(ACAdaptee ac) throws Exception {
        DC20Adapter dc20 = null;
        for(DC20Adapter adapter:this.adapters){
            if(adapter.support(ac)){
                dc20 = adapter;
                break;
            }
        }
        if(dc20 == null){
            throw new Exception("没找到适配器");
        }
        return  dc20;
    }

    
    public static void main(String[] args) throws Exception {
        Client client = new Client();
        ACAdaptee ac220 = new ChinaACAdaptee();
        DC20Adapter adapter = client.getAdapter(ac220);
        DC20Taget dc20Taget = adapter.outputDC20();

        ACAdaptee ac110 = new AmericaACAdaptee();
        adapter = client.getAdapter(ac110);
        DC20Taget dc20Taget1 = adapter.outputDC20();

        System.out.println("ChinaACAdaptee类适配结果"+dc20Taget.outputDC());
        System.out.println("AmericaACAdaptee类适配结果"+dc20Taget1.outputDC());


    }
}

三、总结

适配器模式可以在不改动原有代码的情况下,满足新的需求,符合面向对象设计原则对修改关闭对扩展开放。 

适配器模式在SpringMVC 中有很有些的事例,可以参考学习(待源码跟踪..........................)。

适配器模式,分为对象适配器模式、类适配器模式,

  • 对象适配器模式:需要适配的对象在适配器类中以组合的方式存在(使用方便灵活)
  • 类适配器模式:需要适配的对象是适配器的父类(java单继承,有一定局限性)

 

你可能感兴趣的:(GOF23)