1. 什么是适配器设计模式?
适配器(Adapter)设计模式是一种结构型设计模式,它允许接口不兼容的类之间进行合作。适配器模式充当两个不兼容接口之间的桥梁,使得它们可以一起工作,而无需修改它们的源代码。
- 目标接口(Target): 定义客户端使用的接口,客户端通过该接口与适配器进行交互。
- 适配器(Adapter): 实现目标接口,并且持有一个被适配者的实例,将客户端的请求转换为被适配者能够处理的形式。
- 被适配者(Adaptee): 拥有一组不兼容目标接口的方法,适配器通过包装被适配者,使其能够与目标接口协同工作。
- 客户端(Client): 通过目标接口与适配器进行交互,无需直接与被适配者打交道。
2. 设备接口示例
在给出的示例中,使用python适配器模式,设计个设备通用控制接口,以适配不同厂商的控制接口,主要功能为:
- 初始化设备接口
- 发送控制命令
- 转换数据,用以适应不同设备接口要求
代码如下,不包括具体接口代码内容:
# 定义目标接口
class DataInterface:
def post(self, data):
pass
# 初始化接口url及相关header等内容
def init_url(self):
pass
# 第一个厂商的数据接口
class Vendor1DataInterface:
def send(self, data):
print("Sending data to Vendor 1 API:", data)
def init(self, url):
print("Init Vendor 1 API")
# 第二个厂商的数据接口
class Vendor2DataInterface:
def transfer(self, data):
print("Transferring data to Vendor 2 API:", data)
def set(self,url):
print("Set Vendor 2 API")
# 适配器类,用于将不同厂商的数据接口适配到目标接口
class Vendor1Adapter(DataInterface):
def __init__(self, vendor1_interface):
self.vendor1_interface = vendor1_interface
def init_url(self, url):
self.vendor1_interface.init(url)
def post(self, data):
# 在这里进行数据格式转换
formatted_data = self._format_data(data)
self.vendor1_interface.send(formatted_data)
def _format_data(self, data):
# 这里可以实现数据格式转换的逻辑,例如将数据格式转换为特定格式
return f"Formatted for Vendor 1: {data}"
class Vendor2Adapter(DataInterface):
def __init__(self, vendor2_interface):
self.vendor2_interface = vendor2_interface
def init_url(self, url):
self.vendor2_interface.set(url)
def post(self, data):
# 在这里进行数据格式转换
formatted_data = self._format_data(data)
self.vendor2_interface.transfer(formatted_data)
def _format_data(self, data):
# 这里可以实现数据格式转换的逻辑,例如将数据格式转换为特定格式
return f"Formatted for Vendor 2: {data}"
# 客户端代码
if __name__ == "__main__":
# 假设要使用第一个厂商的数据接口
vendor1_interface = Vendor1DataInterface()
adapter1 = Vendor1Adapter(vendor1_interface)
adapter1.init_url("url 1")
adapter1.post("Data to Vendor 1")
# 假设要使用第二个厂商的数据接口
vendor2_interface = Vendor2DataInterface()
adapter2 = Vendor2Adapter(vendor2_interface)
adapter2.init_url("url 2")
adapter2.post("Data to Vendor 2")
注:此代码改自chatgpt。
在上文的示例中,我们使用了适配器模式,以下是适配器模式的角色及其解释:
-
目标接口(Target):
在示例中,DataInterface 就是目标接口。它定义了客户端期望的操作,包post 方法。在适配器模式中,客户端与目标接口交互,不直接与具体的被适配者进行通信。 -
适配器(Adapter):
在示例中,Vendor1Adapter 和 Vendor2Adapter 是适配器。适配器实现了目标接口,并且包含一个对应的被适配者对象,它们负责将被适配者的接口转换为目标接口。适配器通过委托被适配者来实现目标接口的方法。 -
被适配者(Adaptee):
在示例中,Vendor1DataInterface 和 Vendor2DataInterface 是被适配者。它们是已经存在的类或接口,但是它们的接口与客户端所期望的接口不兼容。适配器将这些不兼容的接口转换为目标接口,使得客户端可以通过适配器与被适配者交互。 -
客户端(Client):
在示例中,客户端代码是指最后的if name == “main”: 部分。客户端通过目标接口与适配器交互,而不需要了解适配器内部是如何处理数据的。客户端不直接与被适配者交互,而是通过适配器间接与被适配者进行通信。这部分也可以直接拿出来,封装成函数来调用。
3. 小结
适配器模式的关键在于将不兼容的接口进行适配,使得它们能够协同工作,而客户端不需要关心具体的接口实现细节,只需要通过目标接口与适配器交互即可。
在给出的示例中,使用的是对象适配器模式,而不是类适配器模式。
-
对象适配器:
对象适配器使用组合关系来连接适配器和被适配者。在示例中,Vendor1Adapter 和 Vendor2Adapter 类通过将被适配者对象作为其一个成员变量来实现适配器功能。在对象适配器中,适配器通过调用被适配者对象的方法来实现目标接口。 -
类适配器:
类适配器使用继承关系来连接适配器和被适配者。适配器类同时继承目标接口和被适配者类,在适配器类中重写目标接口方法,并在重写的方法中调用被适配者类的方法来实现适配。在Python中,由于多重继承的实现复杂性和一些限制,类适配器模式在Python中不太常见。
参考:
天河书阁 VicRestart. Python 如何实现适配器设计模式?什么是适配器(Adapter)设计模式?.CSDN博客 . 2023.11
北京-临渊. Python设计模式-05-适配器模式. 博客园. 2023.06