导言
在软件设计中,为了解决接口不一致的问题,两个软件模块之间往往需要通过一个适配器类 Adapter 进行“适配”。这样的模式叫做适配器设计模式。该模式可以分为两种,分别为类适配器模式(Class Adapter Pattern)和对象适配器模式(Object Adapter Pattern),如图所示。
类适配器模式
这里以问题引入类适配器模式的概念。在图中,假如要使用类 Adaptee 中的方法 Operation1,同时也要使用另外一个方法 Operation2,而 Operation2 没有在类 Adaptee 中,怎样解决该问题呢?
一种解决方案是修改类 Adaptee,在该类中增加代码的实现方法 Operation2。
显然这种方案不可取,因为用户很可能没有该类的源代码,而只有可运行的程序。即使有该类的源代码,修改一个成熟、可靠的类代码,加入新功能的做法只能取得事倍功半的效果。
另一个解决方案是用一个 Target 接口声明所有需要的方法,并且用另外一个 Adapter 类实现 Target 接口中所有的方法。同时,Adapter 类继承 Adaptee 类,如图所示。
将这种结构称为类适配器模式。
类适配器模式的设计要点为,写一个 Target 接口声明所有需要的方法 Operation1 和 Operation2;写一个 Adapter 类继承 Adaptee 类,并且实现接口 Tareget。
适配器模式的各组成部分说明如下。
from abc import ABC, abstractmethod
class Target(ABC):
@abstractmethod
def operation1(self):
pass
@abstractmethod
def operation2(self):
pass
class Adaptee:
def operation1(self):
str(self)
print('adaptee.operation1')
class Adapter(Adaptee, Target):
def __init__(self):
self.adaptee = Adaptee()
def operation2(self):
print('adaptee.operation2')
if __name__ == '__main__':
adapter = Adapter()
adapter.operation1()
adapter.operation2()
对象适配器模式
假设要使用 Adaptee 类中的方法 Operation1,同时要使用不在该类中的方法 Operation2,前面已采用了类适配器模式的解决方案,这里将介绍另一种解决方案,即遵照类适配器模式相同的思路,但是在 Adapter 类中,采用聚合的办法来实现 Operation1,这种方法即对象适配器模式,其设计图如图所示。
对象适配器模式的设计要点为,在接口 Target 类中声明方法 Operation1 与 Operation2,在 Adapter 类中,需要实现两个方法 Operation1 与 Operation2。在实现 Operation1 时,其代码中实现对 Adaptee 的 Operation1 的调用。
类适配器模式与对象适配器模式在形式上的区别是,类适配器模式对被适配对象采用了继承,而对象适配器对被适配对象采用的则是调用。
from abc import ABC, abstractmethod
class Target(ABC):
@abstractmethod
def operation1(self):
pass
@abstractmethod
def operation2(self):
pass
class Adaptee:
def operation1(self):
str(self)
print('adaptee.operation1')
class Adapter(Target):
def __init__(self):
self.adaptee = Adaptee()
def operation1(self):
self.adaptee.operation1()
def operation2(self):
print('adaptee.operation2')
if __name__ == '__main__':
adapter = Adapter()
adapter.operation1()
adapter.operation2()
关于适配器模式的讨论
何时使用适配器模式
在下列情况下可以使用适配器模式。
适配器模式的作用
适配器模式是将接口不同而功能相近的两个接口加以转换,包括适配器角色补充一些原角色没有但目标接口需要的方法。
但不要以为适配器模式就是为了补充原角色没有的方法而准备的。适配器模式可以用于增加新的方法,但是,其主要意图是转换接口。
适配器模式把一个类的接口转换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作,因此,该模式又称为转换器模式、变压器模式、包装(Wrapper)模式(把已有的一些类包装起来,使之能够有满足需要的接口)等。
适配器模式使得一个系统可以使用那些接口和需求不一致的类,尤其对离架产品代码、工具箱和类库更为适用。适配器模式的重要贡献是强调针对接口编程,客户程序直接针对 Target 接口进行编程。
类适配器模式与对象适配器模式的区别
如果一个被适配源类中有大量的方法,使用类适配器模式比较容易,只需要让 Adapter 类继承被适配的源类即可。而此时使用对象适配器模式则要在 Adapter 类中明确写出 Target 角色中的每个方法,并且在每个方法中要一一调用被适配的源类中的相应方法。
本文分享自 Python机器学习算法说书人 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!