适配器模式(Adapter Pattern)
定义
适配器模式,将一个接口转换客户希望的另一个接口。适配器将原本不能在一起工作的接口转换成可以在一起工作的接口”
《大话设计模式》
适配器模式一般应用在不能修改源码,在只提供库的情况下又要适配现有代码,则需要增加一层适配器层。个人理解就是在两个不完全比配的接口之间增加一层代码使之匹配。
适配器出现的目的是为了保证不违反面向对象编程的开放封闭原则
UML 示例
@startuml
class Target
class Client
class Adapter
class Adaptee
Target <|-- Adapter
Target <-- Client
Adaptee <-- Adapter
@enduml
Adapter实现了Target方法,client最终只是访问target接口类型,Adapter为了使Adaptee可以被client访问,所以做了一层适配,Adapter中存在Adaptee类对象
代码实现
在精通python设计模式中,关于适配器模式的介绍,实现也是相当简单的,只要实现目标接口方法,
# 外部类
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(object):
'''
这就是适配器类,通过简单的对象解决了这个问题,即将需要适配的目标对象的内容,添加到适配器对象中,
key:就是目标对象的方法,value:就是需要适配的方法。
而将需要适配的对象的obj的字典内容(保存了属性信息等)添加到适配器中,这样属性性信息也能够被调用了
'''
def __init__(self, obj, adaptermethod):
self.obj = obj
self.__dict__.update(adaptermethod)
self.__dict__.update(obj.__dict__)
super().__init__()
def __str__(self):
return str(self.obj)
from external.external import Synthesizer, Human
# Synthesizer 和 Human,都是external外部包的两个类,他们都有各自的paly和speak方法,
# 但client只知道Computer的调用方法即excute,所以在保证原有代码执行excute保持不变,就是适配器需要做的了。
class Computer(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'the {} computer'.format(self.name)
def execute(self):
return 'executes a program'
def main():
objects = [Computer('Asus')]
synth = Synthesizer('moog')
# 在增加一个适配器类保证Synthesizer也能够被调用
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('name: {}'.format(i.name))
if __name__ == "__main__":
main()
知识点
- 重点理解对象的__dict__字典存储的内容,存储对象的属性信息和方法信息,有兴趣可以调试看看
# 输出 i.__dict__的内容
{'execute': <bound method Synthe...0af6c080>>, 'name': 'moog', 'obj': <external.external.S...10af6c080>}
'execute':<bound method Synthesizer.play of <external.external.Synthesizer object at 0x10af6c080>>
'name':'moog'
'obj':<external.external.Synthesizer object at 0x10af6c080>
__len__:3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。