python设计模式:适配器模式

通常情况下,原系统的代码要么无法获取(如库等)要么难以冒险重构(如运行5年以上的老旧系统牵一发而动全身),在设计中使用适配器模式,可以保证在不修改原系统代码的前提下,实现新需求与原系统的对接。

新旧代码兼容的案例

存在一套旧系统,里面包含Synthesizer类和Human类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Synthesizer:
def __init__(self, name):
self.name = name

def __str__(self):
return '音响合成器:{} '.format(self.name)

def play(self):
return '播放一首电子乐'

class Human:
def __init__(self, name):
self.name = name

def __str__(self):
return '人员:{} '.format(self.name)

def speak(self):
return '向你问好'

现在新增Computer类如下:

1
2
3
4
5
6
7
8
9
class Computer:
def __init__(self, name):
self.name = name

def __str__(self):
return '计算机:{} '.format(self.name)

def execute(self):
return '执行一个程序'

客户端仅知道如何调用execute()方法,并不知道旧系统的Synthesizer.play()和Human.speak(),而他们希望像调用Computer.execute()一样使用来调用原系统中对象的执行函数。
这时候就需要用到适配器了!我们可以创建一个Adapter类专门用于统一接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Synthesizer:
def __init__(self, name):
self.name = name

def __str__(self):
return '音响合成器:{} '.format(self.name)

def play(self):
return '播放一首电子乐'

class Human:
def __init__(self, name):
self.name = name

def __str__(self):
return '人员:{} '.format(self.name)

def speak(self):
return '向你问好'

class Computer:
def __init__(self, name):
self.name = name

def __str__(self):
return '计算机:{} '.format(self.name)

def execute(self):
return '执行一个程序'

class Adapter:
"""
适配器
提供统一接口
"""
def __init__(self, obj, adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)

def __str__(self):
return str(self.obj)

if __name__ == "__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('type is {}'.format(type(i)))

可以看到,扩展系统实现的Computer类的对象因为不需要使用适配器处理,所以被识别为Computer类,但是经过Adapter处理后的synth和human对象已经不能被识别为Synthesizer和Human类,而是被识别为 Adapter类了。如此一来,就实现了统一接口的目标。
适配器模式在需要进行增量式开发的系统中是非常有用的,可以在不修改旧系统的前提下,保证代码的一致性。在合适的场景下有效的提高了代码的健壮性和兼容性。