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

相关推荐
煤泥做不到的!16 分钟前
挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存
开发语言·c++
F-2H19 分钟前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
bryant_meng1 小时前
【python】OpenCV—Image Moments
开发语言·python·opencv·moments·图片矩
若亦_Royi2 小时前
C++ 的大括号的用法合集
开发语言·c++
KevinRay_2 小时前
Python超能力:高级技巧让你的代码飞起来
网络·人工智能·python·lambda表达式·列表推导式·python高级技巧
Captain823Jack2 小时前
nlp新词发现——浅析 TF·IDF
人工智能·python·深度学习·神经网络·算法·自然语言处理
资源补给站3 小时前
大恒相机开发(2)—Python软触发调用采集图像
开发语言·python·数码相机
Captain823Jack3 小时前
w04_nlp大模型训练·中文分词
人工智能·python·深度学习·神经网络·算法·自然语言处理·中文分词
m0_748247553 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
6.943 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala