Python适配器模式实战:解决接口统一与属性访问问题
本文深入解析Python中适配器模式的应用,通过具体代码示例展示如何将Computer、Synthesizer和Human类统一为客户端期望的接口。重点探讨当所有类拥有name属性时初始实现失败的常见陷阱,并提供通过对象委托修复该问题的完整方案,确保在统一执行接口的同时保留原始对象的属性访问能力。
Python适配器模式核心概念与代码实现
Python适配器模式的核心在于通过代码实现来转换接口,使现有类能够被客户端以统一的方式调用。这一过程不仅涉及逻辑适配,还需要对代码结构进行细致思考,确保在不修改源类代码的前提下实现功能兼容。
# -*- coding: utf-8 -*-
# author:baoshan
class Computer:
def __init__(self, name):
self.name = name
def __str__(self):
return 'the {} computer'.format(self.name)
def execute(self):
return 'executes a program'
class Synthesizer:
def __init__(self, name):
self.name = name
def __str__(self):
return 'the {} synthesizer'.format(self.name)
def play(self):
return 'is playing an electronic song'
class Human:
def __init__(self, name):
self.name = name
def __str__(self):
return '{} the human'.format(self.name)
def speak(self):
return 'says hello'
class Adapter:
def __init__(self, obj, adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)
def __str__(self):
return str(self.obj)
def main():
objects = [Computer('Asus')]
synth = Synthesizer('moog')
objects.append(Adapter(synth, dict(execute=synth.play)))
human = Human('Bob')
objects.append(Adapter(human, dict(execute=human.speak)))
for i in objects:
print('{} {}'.format(str(i), i.execute()))
if __name__ == '__main__':
main()
运行上述代码后,控制台输出显示各对象已成功执行其对应行为:计算机执行程序,合成器播放电子乐,人类发出问候。
the Asus computer executes a program
the moog synthesizer is playing an electronic song
Bob the human says hello
------------------------------------------------------------------------------------------
通过适配器模式,我们成功使Human和Synthesizer类与客户端预期的接口保持一致,且无需修改它们的原始源代码。这种解耦方式极大地提升了代码的灵活性和可维护性,体现了设计模式的优越性。
适配器模式常见陷阱:属性访问失败分析
这里有一个具有挑战性的练习:当前实现存在一个潜在问题。当所有类都包含name属性时,尝试直接访问该属性的代码会运行失败,导致程序报错。
for i in objects:
print('{}'.format(i.name))
首先分析这段代码失败的原因。虽然从编码实现角度看逻辑自洽,但对于客户端代码而言却缺乏意义。客户端不应关心“适配了什么”或“未适配什么”的内部细节,其核心诉求仅是获得一个统一的接口。那么,如何调整代码以解决此问题并使其正常运行呢?
思考方向在于:如何将未直接适配的部分(如name属性)委托给适配器类内部包含的目标对象,从而在保持统一接口的同时保留原有功能。
解决方案:通过对象委托修复属性访问
具体的解决方案如下所示,通过修改适配器类的初始化逻辑来实现。
将适配器类进行如下修改,关键步骤是在初始化方法中增加一行代码,显式地将目标对象的name属性赋值给适配器实例。
class Adapter:
def __init__(self, obj, adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)
self.name = obj.name
def __str__(self):
return str(self.obj)
随后,在main函数中获取对应的name属性,通过打印语句验证修改后的效果。
def main():
objects = [Computer('Asus')]
synth = Synthesizer('moog')
objects.append(Adapter(synth, dict(execute=synth.play)))
human = Human('Bob')
objects.append(Adapter(human, dict(execute=human.speak)))
for i in objects:
print('{} {}'.format(str(i), i.execute()))
print('{}'.format(i.name))
if __name__ == '__main__':
main()
运行结果如下,显示各对象既执行了统一接口的方法,又正确输出了各自的name属性。
the Asus computer executes a program
Asus
the moog synthesizer is playing an electronic song
moog
Bob the human says hello
Bob
本文内容参考自《精通Python设计模式》一书,旨在帮助读者深入理解设计模式的实际应用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













