Python之适配器模式
一、介绍
结构型设计模式:主要用来处理一个系统中不同实体之间关系,即将类或者对象组合在一起,重新组成为一种新的、功能更强大的结构。
- 类结构型模式:多个类组合而成的系统。
- 对象结构型模式:在一个类中定义另外一个类的实例,通过类与对象的组合形成更大的系统,可以通过类中的对象属性去调用这个对象的方法。
适配器模式:也是属于设计模式中的结构型模式。
适配器模式主要用于 帮助我们实现两个不兼容接口之间的兼容。
二、适配器模式
1、对象结构型适配器示例
假设存在一套旧的系统ExecuteCmd类,用来执行一些系统命令。
import subprocess class ExecuteCmd: def __init__(self, cmd): self.cmd = cmd def cmd_exe(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code
客户端要执行命令的时候,只需要调用这个类的实例方法cmd_exe即可:
old_obj = ExecuteCmd("ls -l").cmd_exe()
现在有一个新的系统,仍然是用来执行一些系统命令,但是新的调用方式改变了。
class NewCmd: def __init__(self, cmd): self.cmd = cmd def run_cmd(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code
新的调用方式是:
new_obj = NewCmd("ls -l").run_cmd()
假设由于新系统支持的命令更多,我们想要把新系统也提供给客户端使用,但是客户端只知道使用某个实例的cmd_exe方法,并不知道新系统的调用方式改变了。
在不改变新系统NewCmd类的前提下,我们该如何做才能让客户端仍然能正常调用呢?
此时就需要用到适配器!我们可以创建一个通用的Adapter类,将一些不同接口的对象适配到一个统一接口中。
在初始化方法init()中,用一个属性obj把我们想要适配的对象保存下来, adapted_methods是一个字典,用于转换接口,key是客户端要调用的方法,value是想要适配的对象真正被调用的方法。
适配器类定义如下:
class Adapter: def __init__(self, obj, adapted_methods): self.obj = obj self.obj.__dict__.update(adapted_methods) def __getattr__(self, item): return self.obj.__dict__[item]
使用方法如下:
# 旧接口可以不适配 old_obj = ExecuteCmd("ls -l").cmd_exe() # 新接口需要进行适配 new_obj = NewCmd("ls -l") trans_obj = Adapter(new_obj, dict(cmd_exe=new_obj.run_cmd)) # 适配完成后,就可以跟旧系统一样使用cmd_exe执行命令 trans_obj.cmd_exe()
完整的代码展示
import subprocess class ExecuteCmd: def __init__(self, cmd): self.cmd = cmd def cmd_exe(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code class NewCmd: def __init__(self, cmd): self.cmd = cmd def run_cmd(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code class Adapter: def __init__(self, obj, adapted_methods): self.obj = obj self.obj.__dict__.update(adapted_methods) def __getattr__(self, item): return self.obj.__dict__[item] # 旧接口可以不适配 old_obj = ExecuteCmd("calc").cmd_exe() # 新接口需要进行适配 new_obj = NewCmd("calc") # 这里将新系统的run_cmd方法适配成旧系统的cmd_exe方法 trans_obj = Adapter(new_obj, dict(cmd_exe=new_obj.run_cmd)) # 适配完成后,就可以跟旧系统一样使用cmd_exe执行命令 trans_obj.cmd_exe()
2、类结构型适配器示例
如果我们希望直接使用一个新的类去适配旧系统的接口时,也可以使用类结构型适配器,方法如下:
- 创建一个新的类
- 继承需要进行转换的类
- 在新的类中实现旧系统的接口
import subprocess class ExecuteCmd: def __init__(self, cmd): self.cmd = cmd def cmd_exe(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code class NewCmd: def __init__(self, cmd): self.cmd = cmd def run_cmd(self): result = "" result_code = 0 try: result = subprocess.check_output(self.cmd, shell=True) except subprocess.CalledProcessError as e: result_code = 1 return result, result_code class Adapter(NewCmd): """继承新系统的类""" def cmd_exe(self): """直接在适配器中实现旧系统的接口""" return self.run_cmd() # 旧接口 old_obj = ExecuteCmd("calc").cmd_exe() # 新接口需要进行适配 new_obj = Adapter("calc").cmd_exe()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix