文章目录

  • 1.实现适配器模式。
  • 2.适配器模式的优势
  • 3.适配器模式适用场景
  • 4.摘要

适配器在生活中无处不在,比如电脑适配器,读卡器,电源适配器。它们的共同点是接口标准不同,需要通过一个适配器转换后才能使用。以读卡器为例,存储卡的接口只能适配相机或手机的卡槽。而电脑一般都是USB接口。那么如何使用电脑上的存储卡呢?我们可以用读卡器。一个卡槽可以插存储卡,另一个USB可以插电脑。适配器可以解决接口不兼容的问题。再比如电脑的变压器。电脑一般接收20V电压,而我们国家的电压是220V,所以需要一个变压器进行转换。如下图所示,输入电压为220V,输出电压转换为20V。变压器实际上是一个适配器。

1.实现适配器模式。

让我们以下面的例子来看看如何实现适配器模式。如果我们的电视屏幕输出4K画质,但是播放器只能输出2K画质,那么就需要一个适配器来完成从2K到4K的转换。代码如下:

只能输出2k信号的播放器:

public class Player { public TwoThousandSignal play() { return new TwoThousandSignal(); }}

我们定义了一个更现代的播放器的接口,它输出4K信号:

public interface ModernPlayer { FourThousandSignal play();}

这个接口的实现是一个适配器。通过复用播放器输出的2K信号,转换成4K信号,支持ModernPlayer的设备可以播放2K信号源。

public class ModernPlayerAdapter implements ModernPlayer { private Player player = new Player(); @Override public FourThousandSignal play() { TwoThousandSignal twoThousandSignal = player.play(); return convertToFourThousandSignal(twoThousandSignal); } private FourThousandSignal convertToFourThousandSignal(TwoThousandSignal twoThousandSignal) { //4k信号通过算法计算,从2k转换而来。省略转换逻辑, return new FourThousandSignal(); }}

作为电视的调用者,你只需要使用ModernPlayerAdapter的实例来播放2K信号。代码如下:

public class Television { private ModernPlayer modernPlayer = new ModernPlayerAdapter(); public void display(){ modernPlayer.play(); }}

看看代码看起来像不像代理模式?ModernPlayerAdapter只是调用Adaptee的方法,将2k信号转换成4K信号。区别在于播放器没有实现ModernPlayer接口。代理模式、Proxy和RealSubject都需要实现相同的接口。适配器的作用是适应不同的接口。两个接口的返回值不同,所以转换逻辑需要在Adapter中实现。

类图:

2.适配器模式的优势

不需要修改现有的接口和实现,就能复用已有的类;灵活度高,可以在接口不变的情况下,兼容多种不同的类。

3.适配器模式适用场景

想要使用一个已有的类,但是此类的接口并不符合使用方要;多个类做的事情相同或者类似,但是各自接口又不同。调用方希望统一接口。

第一场可以认为是亡羊补牢,为时已晚。由于各种原因,系统界面不同,但功能相似。这时候很有可能无法直接修改已有的接口,只能通过适配器模式来适配这个接口。

第二个场景其实很常见。比如我们开发一个比价网站,需要从不同的网站抓取同类产品的价格,然后按照自己系统的数据结构进行保存。不同网站抓取的数据肯定是不一样的,字段名不一样,或者数据结构不一样。但是最后都要保存在同一个数据结构中,这个时候就需要适配器进行转换。

4.摘要

当我们面对难以转换的对象,想要重用时,可以考虑采用适配器模式。但是切记不要滥用适配器。在最初设计程序时,我们应该考虑代码的可扩展性。而不是最终通过适配器解决问题。能修改重构的,尽量修改。如果不能修改,比如外系统的接口,那就只能通过适配器模式来解决了。

发表评论

后才能评论