Adapter - 适配器设计模式

43 阅读3分钟

什么是适配器模式?

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

上升到系统对接层面,做系统集成项目的小伙伴会比较了解,不同系统的 API 往往会有很大的差异,想要把两个系统串联起来会需要一个独立的程序在中间做适配。就拿下 A 公司要给 B 公司单场景为例,A 系统提供一个标准的取订单信息的接口,B 系统提供了标准的下单接口,显然这两个接口都是独立而不可修改的,这时我们就可以采用适配器思想,独立运行一个程序去拉 A 的下单信息再扭派给 B 系统来下单,最终实现对接。

优缺点

优点:

1.可以让任何两个没有关联的类一起运行。
2.提高了类的复用。
3.增加了类的透明度。
4.灵活性好。

缺点:

1.过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

注意事项

适配器不是在详细设计时添加的,而是解决正在服役或迁移的项目的问题。正常开发时能不用尽量不用。

示例

两家公司的订单系统中,定义的 OrderBean 属性不同,处理的的接口方法也不同,我们想要用适配器模式帮我们实现 A 公司处理 B 公司的订单的。首先是两个 Order 类:

class CompanyAOrder {
    protected String id;
    protected String name;
    protected String produceInfo() {
        return this.id + '-' + this.name;
    }
}

class CompanyBOrder {
    protected String number;
    protected String name;
    public CompanyBOrder(String number, String name) {
        this.number = number;
        this.name = name;
    }
    protected String print() {
        return this.number + '-' + this.name;
    }
}

公司 A 中定义一个 process 方法,只接受 CompanyAOrder 类型的对象,而 B 公司的订单接口中只有一个 print 方法,并不能拿来直接用。我们构造一个 Adapter

class CompanyA {
    public void process(CompanyAOrder order) {
        System.out.println(order.produceInfo());
    };
}
    
class CompanyAOrderAdapter extends CompanyAOrder {
    private CompanyBOrder companyBOrder;
    public CompanyAOrderAdapter(CompanyBOrder companyBOrder) {
        this.companyBOrder = companyBOrder;
    }
    @Override
    public String produceInfo() {
        return this.companyBOrder.print();
    }
}
    
public static void main(String[] args) {
    final CompanyA companyA = new CompanyA();
    final CompanyBOrder companyBOrder = new CompanyBOrder("BC-001", "The first order for company B");
    companyA.process(new CompanyAOrderAdapter(companyBOrder));
}

Output:

BC-001 - The first order for company B

我们可以到,A 公司已经成功处理了 B 公司的订单。

适配器模式和装饰者模式的区别?

从形式上看两者都是属于包装模式,但其作用和结果不同。装饰器模式目的是在不改变接口的前提下增强功能,而适配器式的目的是要彻底改变接口。说的更具体点,装饰器解决的是可以用但好不好用的问题,适配器解决的是能不能让接口用得起来的问题。