1.背景
在面向对象对象编程中,我们常提到要分离关注点;但当我们将代码重构为若干职责单一的类之后又发现类与类之间的调用关系或通信会变得复杂。
而设计模式中的“迪米特法则”又要求如果两个类之间没有必要直接通信那么他们之间就不应该产生直接的关联关系。由此我们可以想到可以在众多需要相互对象之间引入一个中间节点,来负责类与类之间的通讯转发。
中介者模式(Mediator): 用一个中介对象来封装一系列的对象交互中介者使得=各对象不需要显示的相互引用,从而使其松耦合,而且可以独立地改变他们之间的交互。
2.Demo需求:
中介者模式让我想到了一个典型的案例就是Ethernet交换机。如果没有交换机网络上N个节点两两通讯,理论上需要N(N-1)/2个链接。但使用了交换机以后则仅需要N个链接,交换机就是一个典型的中介者。下面来写一段示意代码,来展示中介者模式
3.中介者模式实现Demo:
‘
class Switch:
def __init__(self):
self._devices=[]
def forward(self,target_mac,msg):
# 基于目的MAC转发
for device in self._devices:
if device.mac == target_mac:
device.rcv_pkt(msg)
def build_forward_table(self,*devices):
self._devices = devices
class PC:
def __init__(self,mac,switch):
self.mac = mac
self._sw = switch
def send_pkt(self,target_mac,msg):
print('PC Send %s to %s' % (msg,target_mac))
self._sw.forward(target_mac, msg)
def rcv_pkt(self,msg):
print('PC Rcv Pkt: %s' % msg)
class SetTopBox:
def __init__(self,mac,switch):
self.mac = mac
self._sw = switch
def send_pkt(self, target_mac,msg):
print('set_top_box Send %s to %s' % (msg,target_mac))
self._sw.forword(target_mac, msg)
def rcv_pkt(self, msg):
print('set_top_box Rcv Pkt: %s' % msg)
class TV:
def __init__(self,mac,switch):
self.mac = mac
self._sw = switch
def send_pkt(self, target_mac,msg):
print('TV Send %s to %s' % (msg,target_mac))
self._sw.forword(target_mac,msg)
def rcv_pkt(self, msg):
print('TV Rcv Pkt: %s' % msg)
if __name__ == '__main__':
zx_zxr10 = Switch()
test_pc = PC('11-11-11-11-11-11',zx_zxr10)
test_set_top_box = SetTopBox('22-22-22-22-22-22',zx_zxr10)
test_tv = TV('33-33-33-33-33-33',zx_zxr10)
zx_zxr10.build_forward_table(test_pc,test_set_top_box,test_tv)
test_pc.send_pkt('33-33-33-33-33-33', 'PING')
’
执行结果:
/Users/hellfire/Documents/设计模式复习/venv/bin/python /Users/hellfire/Documents/设计模式复习/Mediator/mediator.py
PC Send PING to 33-33-33-33-33-33
TV Rcv Pkt: PING
Process finished with exit code 0
说明:
本例示意的交换机数据转发过程与实际还是有较大差异,但基本上能够体现“中介者”模式的核心:
Switch为中介者类,它通过目的Mac来转发链接在它上的网络设备的数据报文。而每个网络设备类:PC、TV、SetTopBox 只需要将报文递交给所依赖的switch对象负责报文处理,不需要与其它网络设备类形成耦合关系。
4.中介者模式缺陷:
在真实项目应用中,中介者可能会存在过于负责,职责过重的情况。