python适配器模式开发实践

1. 什么是适配器设计模式?

适配器(Adapter)设计模式是一种结构型设计模式,它允许接口不兼容的类之间进行合作。适配器模式充当两个不兼容接口之间的桥梁,使得它们可以一起工作,而无需修改它们的源代码。

  • 目标接口(Target): 定义客户端使用的接口,客户端通过该接口与适配器进行交互。
  • 适配器(Adapter): 实现目标接口,并且持有一个被适配者的实例,将客户端的请求转换为被适配者能够处理的形式。
  • 被适配者(Adaptee): 拥有一组不兼容目标接口的方法,适配器通过包装被适配者,使其能够与目标接口协同工作。
  • 客户端(Client): 通过目标接口与适配器进行交互,无需直接与被适配者打交道。

2. 设备接口示例

在给出的示例中,使用python适配器模式,设计个设备通用控制接口,以适配不同厂商的控制接口,主要功能为:

  • 初始化设备接口
  • 发送控制命令
  • 转换数据,用以适应不同设备接口要求

代码如下,不包括具体接口代码内容:

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

相关推荐
2601_9577808432 分钟前
Claude 4.6 对阵 GPT-5.4:2026 开发者大模型 API 选型深度解析
人工智能·python·gpt·ai·claude
2601_9577808432 分钟前
GPT-5.5 深度解析:2026年4月OpenAI旗舰模型的技术跨越与商业决策指南
大数据·人工智能·python·gpt·openai
zhaoyong2221 小时前
SQL如何统计每个用户的首次行为时间_MIN聚合与分组
jvm·数据库·python
2501_901006471 小时前
C#怎么实现配置热更新 C#如何在运行时动态刷新配置文件不需要重启程序【技巧】
jvm·数据库·python
m0_470857641 小时前
HTML怎么创建响应式图片备选方案_HTML srcset与sizes结构【详解】
jvm·数据库·python
InfinteJustice2 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft
码云数智-大飞2 小时前
滥用Lombok的@EqualsAndHashCode导致线上事故复盘
开发语言
yong99902 小时前
C# 实时查看硬件使用率(CPU 内存 硬盘 网络)
开发语言·网络·c#
不午休の野猫2 小时前
vs + qt环境编译.sln项目时报无法解析的外部符号metaObject && qt_metacast
开发语言·qt
2301_795099742 小时前
如何优化SQL中大批量数据的物理删除_分批次与间隔控制
jvm·数据库·python