4.2 解 决 方 案

4.2.1 使适配器模式来解决问题

用来解决上述问题的一个合理的解决方案就是适配器模式。那么什么是适配器模式呢?

1.适配器模式的定义

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

2.应用适配器模式来解决问题的思路

仔细分析上面的问题,问题的根源在于接口的不兼容,功能是基本实现了的,也就是说,只要想办法让两边的接口匹配起来,就可以复用第一版的功能了。

按照适配器模式的实现方式,可以定义一个类来实现第二版的接口,然后在内部实现的时候,转调第一版已经实现了的功能,这样就可以通过对象组合的方式,既复用了第一版已有的功能,同时又在接口上满足了第二版调用的要求。

完成上述工作的这个类就是适配器。

4.2.2 适配器模式的结构和说明

适配器模式的结构如图4.6所示。

图片

图4.6 适配器模式的结构图

■ Client:客户端,调用自己需要的领域接口Target。

■ Target:定义客户端需要的跟特定领域相关的接口。

■ Adaptee:已经存在的接口,通常能满足客户端的功能要求,但是接口与客户端要求的特定领域接口不一致,需要被适配。

■ Adapter:适配器,把Adaptee适配成为Client需要的Target。

4.2.3 适配器模式示例代码

(1)先看看Target接口定义的示例代码如下:

82a4711cb5974c3db418a3ac7a7cac0e

(2)再看看需要被适配的对象定义。示例代码如下:

6d27dfe31cc94aabaabca1cc2e265591

4fdf4b7a4f8f4c9d9498c66326233b7b

(3)下面是适配器对象的基本实现。示例代码如下:

513a51e7b4914d3a9ad45856f3261bca

(4)再来看看使用适配器客户端的示例代码如下:

c6adb69fd4a54bfba7076712ecc5149a

4.2.4 使用适配器模式来实现示例

要使用适配器模式来实现示例,关键是要实现适配器对象。它需要实现第二版的接口,但是在内部实现的时候,需要调用第一版已经实现的功能。也就是说,第二版的接口就相当于适配器模式中的Target接口,而第一版已有的实现就相当于适配器模式中的Adaptee对象。

(1)把适配器简单的实现出来,示意一下。示例代码如下:

85dd9902243a4c02ba22324c26ee5713

c31530f2ce494e01b350085590c24de2

(2)此时的客户端也需要一些改变。示例代码如下:

aecceabff3f741adbcc85ba4ef9759db

运行上述代码,测试其是否能满足要求。

(3)下面总结一下这个思路。

⑴原有文件存取日志的方式,运行得很好,如图4.7所示。

图片

图4.7 原有文件存取日志的方式

⑵现在有了新的基于数据库的实现,新的实现有自己的接口,如图4.8所示。

图片

图4.8 新的基于数据库的实现

⑶现在想要在第二版的实现里面,能够同时兼容第一版的功能,那么就应有一个类来实现第二版的接口,然后在这个类里面去调用已有的功能实现,这个类就是适配器,如图4.9所示。

图片

图4.9 加入适配器的实现结构示意图

上面是分步的思路,下面来看一下前面示例的整体结构,如图4.10所示。

图片

图4.10 适配器实现示例的结构示意图

如同上面的例子,原本新的日志操作接口不能和旧的文件实现一起工作,但是经过适配器适配后,新的日志操作接口就可以和旧的文件实现日志存储一起工作了。