深入浅出设计模式之适配器模式

适配器模式


一、概念

  • 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能在一起工作的 那些类能一起工作。
    适配的意识是适应,匹配。通俗的讲,适配器模式适用于有关性但不兼容的结构,源接口通过一个中间件转换后才可以适用于目标接口,这个转换过程就是适配,这个中间件就称之为适配器。
    比如家用电源输出电压,USB数据线输入电压。但这俩个接口无法兼容,因为一个输出220V,一个输入5V,通过适配器将输入220V转换成输出5V之后才能一个工作。

二、UML图

摘自知乎:https://zhuanlan.zhihu.com/p/369272002
在这里插入图片描述
从上图可见,适配器模式有三个角色

  • Target:是一个接口,它是我们客户端使用的目标借口。
  • Adaptee:我们想要使用的接口与Target不兼容的类,它可以是一个接口,也可以是一个类。
  • Adapter:适配器类,此模式的核心。他需要实现目标接口Target而且必须要引用Adaptee,因为我们要在此类中包装Adaptee的功能。

三、实例

我们列举一个手机充电需要5V电压,而电源提供的是220V的电压,使用适配器解决来解决的栗子。

  • Target
/**
 * <p>5V的电源</P>
 *
 * @author hanchao
 */
public interface V5Power {
    /**
     * 获取名称
     */
    String getName();

    /**
     * 获取电压
     */
    Integer getVoltage();
}

然后定义一个充电宝实现该接口:

/**
 * <p>充电宝</P>
 *
 * @author hanchao
 */
public class PortableBatteryPower implements V5Power {

    @Override
    public String getName() {
        return "充电宝";
    }

    @Override
    public Integer getVoltage() {
        return 5;
    }
}

然后,定义一个手机Phone,它具有充电功能batteryCharge(),其能接受的参数是V5Power类型的。

/**
 * <p>手机</P>
 *
 * @author hanchao
 */
@Slf4j
public class Phone {
    /**
     * 充电
     */
    public void batteryCharge(V5Power v5Power) {
        log.info("1.连接电源 ==> " + v5Power.getName());
        log.info("2.当前电压 : " + v5Power.getVoltage());
        log.info("3.进行充电 ... ");
    }
}
  • Adaptee
/**
 * <p>220V的电源</P>
 *
 * @author hanchao
 */
public interface V220Power {
    /**
     * 获取名称
     */
    String getName();

    /**
     * 获取电压
     */
    Integer getVoltage();
}

220V电源:实现:家用电源:HouseholdPower

/**
 * <p>家用电源</P>
 *
 * @author hanchao
 */
public class HouseholdPower implements V220Power {

    @Override
    public String getName() {
        return "家用电源";
    }

    @Override
    public Integer getVoltage() {
        return 220;
    }
}

因为手机Phone的充电方法batteryCharge(V5Power v5Power)参数是V5Power类型的,肯定无法直接传入V220Power类型的参数。

  • Adapter
    此时,我们需要实现一个适配器Adapter,这个适配器应该实现以下两个功能:
  • 它的类型应是V5Power的,如此才能作为batteryCharge()方法的参数。所以有:Adapter implements V5Power。
  • 它应包含V220Power的对象,如此才能实现最初的目的:使用V220的电源。所以有成员变量:V220Power v220Power。
/**
 * <p>USB接口转换器</P>
 * <p>
 * 1.实现适配目标对象V5Power
 *
 * @author hanchao
 */
@Slf4j
public class V220ToV5Adapter implements V5Power {
    /**
     * 2.以组合的方式持有被适配对象v220Power
     */
    private V220Power v220Power;

    /**
     * 3.在构造时初始化被适配对象v220Power
     */
    public V220ToV5Adapter(V220Power v220Power) {
        this.v220Power = v220Power;
    }

    /**
     * 重写V5Power的方法,完成V220到V5的转换过程
     */
    @Override
    public String getName() {
        return " 电源适配器 ==> " + v220Power.getName();
    }

    /**
     * 重写V5Power的方法,完成V220到V5的转换过程
     */
    @Override
    public Integer getVoltage() {
        log.info("原始电压为:" + v220Power.getVoltage());
        log.info("进行电压转换:" + v220Power.getVoltage() + " --> " + 5);
        log.info("转换之后的电源为:5");
        return 5;
    }
}

测试代码:AdapterDemo

public static void main(String[] args) {
        //首先,需要一部手机
        Phone phone = new Phone();
        log.info("如果只有家用电源,则需要通过电源适配器进行转换");
        V220Power v220Power = new HouseholdPower();
        v5Power = new V220ToV5Adapter(v220Power);
        phone.batteryCharge(v5Power);
    }

测试结果:

2019-07-09 13:01:44,981  INFO [main-1] pers.hanchao.designpattern.adapter.AdapterDemo:26 - 如果只有家用电源,则需要通过电源适配器进行转换 
2019-07-09 13:01:44,985  INFO [main-1] pers.hanchao.designpattern.adapter.Phone:18 - 1.连接电源 ==>  电源适配器 ==> 家用电源 
2019-07-09 13:01:44,985  INFO [main-1] pers.hanchao.designpattern.adapter.adapter.V220ToV5Adapter:41 - 原始电压为:220 
2019-07-09 13:01:44,986  INFO [main-1] pers.hanchao.designpattern.adapter.adapter.V220ToV5Adapter:42 - 进行电压转换:220 --> 5 
2019-07-09 13:01:44,986  INFO [main-1] pers.hanchao.designpattern.adapter.adapter.V220ToV5Adapter:43 - 转换之后的电源为:5 
2019-07-09 13:01:44,986  INFO [main-1] pers.hanchao.designpattern.adapter.Phone:19 - 2.当前电压 : 5 
2019-07-09 13:01:44,986  INFO [main-1] pers.hanchao.designpattern.adapter.Phone:20 - 3.进行充电 ...

该栗子UML图:
在这里插入图片描述

注:该栗子摘于博客地址:https://blog.csdn.net/hanchao5272/article/details/96484044


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值