适配器模式:快速兼容旧接口

548 阅读4分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

总体来说设计模式分为三大类:创建型模式、结构型模式、行为型模式。前面的系列文章都是为创建型模式:

《单例模式——8种实现方式》

《工厂模式:工厂方法模式和抽象工厂模式》

《原型模式:快速复制已有实例创建新的实例》

<建造者模式>

从今天起,我们开始学习结构型模式。

结构型模式:主要用于描述如何组合类和对象以获得更大的结构。

适配器模式

适配器模式(Adapter Pattern)定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作

适配器模式核心意义:兼容旧接口

适配器在我们生活中随处可见,比如电源适配器,很多电器并不是直接使用220V电源,而需要一个电源适配器才能正常使用;还有我们笔记本电脑的外接接口,如果只有一个HDMI接口,想用在只能使用VGA接口上的设备上,我们就需要一个额外转接头,这个转接头我们就称作适配器。

适配器模式原理我们就可以理解成适配器在生活中的作用。

适配器模式包含三个角色:

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

这三种角色用笔记本电脑外接接口例子来说,HDMI接口是我们的目标接口,因为我们电脑提供功能是HDMI接口视频输出;VGA设备就是适配者,我们最终需要把视频输出在VGA设备上;转接头就是我们的适配器

适配器模式编码实现

现在我们有一个1.0版本商城场景,系统刚运行起来,我们没有自营商品,当前的商品都是第三方提供的,所以我们商品下单时,要对接第三方下单服务:

// 第三方订单服务
public class ThirdOrderService {
    // 调用该方法,实现第三方接口下单
    void thirdCreateOrder() {
        System.out.println("第三方服务接口下单");
    }
}

后面我们商城系统发展起来了,对于商城的绝大部分商品,都变为自营的了,后续商品的下单只需要我们调用自己的下单接口。

// 订单服务接口
public interface OrderService {
    /**
     * 创建订单接口
     */
    void createOrder();
}

但是,商城还有少部分是第三方提供的的商品,而我们新的创建订单接口并不兼容旧第三方接口。这时候,我们就可以使用适配器模式,使新的订单接口兼容旧的第三方接口

// 第三方订单接口适配器
public class ThirdOrderServiceAdapter implements OrderService {

    private ThirdOrderService thirdOrderService;

    public ThirdOrderServiceAdapter() {
        thirdOrderService = new ThirdOrderService();
    }

    @Override
    public void createOrder() {
        thirdOrderService.thirdCreateOrder();
    }
}

客户端使用情况

public class Client {
    public static void main(String[] args) {
        OrderService orderService = new ThirdOrderServiceAdapter();
        orderService.createOrder();
    }
}
// 输出结果:
第三方服务接口下单

从客户端调用来看,我们通过第三方订单接口适配器,使新的创建订单接口兼容了旧的第三方接口调用。

对象适配器和类适配器

适配器模式一般有两种不同的适配方法:对象适配和类适配。上面所演示的就是对象适配(通过组合方式)。接下来我们看看类适配器,通过继承方式实现。

public class ThirdOrderServiceAdapter2 extends ThirdOrderService implements OrderService {
    @Override
    public void createOrder() {
        // 调用父类的第三方订单创建接口
        super.thirdCreateOrder();
    }
}

通常,我们喜欢使用组合多于继承,所以更常用的是对象适配方式。类适配方式违背了我们的组合/聚合复用原则