设计模式-桥接模式
问题描述
假设一个智能家居的产品, 要在手机上实现一个遥控器app可以控制所有接入的家电.
大概得结构如下:
classDiagram
direction LR
class RemoteControl{
+ turnOn()
+ turnOff()
}
class TVRemoteControl{
+ setChannel(id)
}
class ACRemoteControl{
+ setTempreature(value)
}
RemoteControl <|-- TVRemoteControl : 继承
RemoteControl <|-- ACRemoteControl : 继承
每一个具体的实现方法都应该包含几个部分:
- App自身的某些逻辑, 比如用户操作日志, 行为分析, 日志处理等等.
- 创建与设备之间的通讯.
- 创建指令消息.
- 向设备发送指令.
可以简单的为一套加点进行完整的操作抽象.
但如果需要增加新的品牌设备增加适配, 通过继承可以解决问题, 比如添加TCLTVRemoteControl
类等.
但是对于特定品牌的遥控器所需要的仅仅只是对应的通讯方式. 而继承父类则会完整获得所有的变量和方法, 使得子类变得臃肿.
同时抽象部分于实现部分则通过继承关系耦合度太高, 对父类的任何修改都会影响到全部子类.
也可以使用适配器模式来解决, 不过通常来说, 适配器更多的是用于让两个已经存在的东西协同工作.
桥接模式则是用于将抽象层和实现层分离. 在架好桥之后两边则可以进行独立维护, 实现层也可以自由扩展.
classDiagram
direction TD
class RemoteControl{
device:Device
+ turnOn()
+ turnOff()
}
class TVRemoteControl{
+ setChannel(id)
}
class ACRemoteControl{
+ setTempreature(value)
}
class Device{
<<interface>>
+ turnOn()
+ turnOff()
}
class DeviceTV{
<<interface>>
+ setChannel(id)
}
class DeviceAC{
<<interface>>
+ setTempreature(value)
}
class SonyTV{
+ setChannel(id)
}
class LGTV{
+ setChannel(id)
}
class HaierAirControll{
+ setTempreature(value)
}
class MediaAirControll{
+ setTempreature(value)
}
RemoteControl *--> Device : 桥接
RemoteControl <|-- TVRemoteControl : 继承
RemoteControl <|-- ACRemoteControl : 继承
Device <|-- DeviceTV
Device <|-- DeviceAC
DeviceTV <|-- SonyTV
DeviceTV <|-- LGTV
DeviceAC <|-- HaierAirControll
DeviceAC <|-- MediaAirControll
简单的python实现
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from abc import ABC, abstractmethod
class Device(ABC):
@abstractmethod
def turn_on(self):
pass
@abstractmethod
def turn_off(self):
pass
class Television(Device):
@abstractmethod
def set_channel(self, channel):
pass
class AirController(Device):
@abstractmethod
def set_temperature(self, temperature):
pass
class SonyTV(Television):
def turn_on(self):
print("Turn on Sony TV.")
def turn_off(self):
print("Turn off Sony TV.")
def set_channel(self, channel):
print(f"Set Sony TV to channel:{channel}")
class MediaAirController(AirController):
def turn_on(self):
print("Turn on Media Air Controller.")
def turn_off(self):
print("Turn off Media Air Controller.")
def set_temperature(self, temperature):
print(f"Set Media Air Controller to: {temperature}°C.")
class RemoteController:
def __init__(self, device: Device):
self._device = device
def turn_on(self):
print("Use Remote Controller to turn on device.")
self._device.turn_on()
def turn_off(self):
print("Use Remote Controller to turn off device.")
self._device.turn_off()
class TVRemoteController(RemoteController):
def __init__(self, device: Television):
super().__init__(device)
def set_channel(self, channel):
print(f"Set TV to channel: {channel}")
if isinstance(self._device, Television):
self._device.set_channel(channel)
class ACRemoteController(RemoteController):
def __init__(self, device: AirController):
super().__init__(device)
def set_temperature(self, temperature):
print(f"set AC to temperature: {temperature}°C")
if isinstance(self._device, AirController):
self._device.set_temperature(temperature)
if __name__ == "__main__":
ac = ACRemoteController(MediaAirController())
tv = TVRemoteController(SonyTV())
tv.turn_on()
tv.set_channel(5)
tv.turn_off()
ac.turn_on()
ac.set_temperature(26)
ac.turn_off()
最终输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
Use Remote Controller to turn on device.
Turn on Sony TV.
Set TV to channel: 5
Set Sony TV to channel:5
Use Remote Controller to turn off device.
Turn off Sony TV.
Use Remote Controller to turn on device.
Turn on Media Air Controller.
set AC to temperature: 26°C
Set Media Air Controller to: 26°C.
Use Remote Controller to turn off device.
Turn off Media Air Controller.
本文由作者按照 CC BY 4.0 进行授权