Posts 设计模式-中介模式
Post
Cancel

设计模式-中介模式

概念解析

中介模式指的是:用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变地改变它们之间的交互。中介模式主要有三个角色:

  • 交互对象(InteractiveObject): 要进行交互的一系列对象
  • 中介者(Mediator):负责协调各个对象之间的交互
  • 具体中介者(Mediator):中介的具体实现

中介模式的优点是:简化了对象之间的交互,将多个调用者和多个实现者这件多对多的交互关系转化为一对多的关系:易于理解、维护和扩展,大大减少了多个对象之间的相互交叉引用的情况。其缺点是:中介者承接了所有的逻辑,交互的复杂度转变成了中介者的复杂度,中介者本身会变得难以维护,且中介者出现问题的时候会导致多个使用者出现问题。 中介模式类图如下: img

设计模板

中介模式模板代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class InteractiveObject:
    """进行交互的对象"""
    pass

class InteractiveObjectImplA:
    """实现类A"""
    pass

class InteractiveObjectImplB:
    """实现类B"""
    pass

class Meditor:
    """中介者"""

    def __init__(self):
        self.__interactiveObjA = InteractiveObjectImplA()
        self.__interactiveObjB = InteractiveObjectImplB()

    def interactive(self):
        """进行交互的操作"""
        # 调用self.__interactiveObjA和self.__interactiveObjB完成相应的交互操作
        pass

实例分析

创建一个设备管理器,进行各种繁杂设备的交互,其中 DeviceUtil+DeviceMgr 为中介者,其中 DeviceUtil 封装了上层的行为,这样对外呈现的时候不需要维护多个DeviceMgr对象。同理,DeviceList维护了不同设备的list,获取整体信息。

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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from abc import ABCMeta, abstractmethod
from enum import Enum


class DeviceType(Enum):
    "设备类型"
    TypeSpeaker = 1
    TypeMicrophone = 2
    TypeCamera = 3


class DeviceTerm:
    "设备项"

    def __init__(self, id, name, type, isDefault=False):
        self.__id = id
        self.__name = name
        self.__type = type
        self.__isDefault = isDefault

    def __str__(self):
        return "type:" + str(self.__type) + " id:" + str(self.__id) \
            + " name:" + str(self.__name) + " isDefault:" + str(self.__isDefault)

    def getId(self):
        return self.__id

    def getName(self):
        return self.__name

    def getType(self):
        return self.__type

    def isDefault(self):
        return self.__isDefault


class DeviceList:
    "设备列表"

    def __init__(self):
        self.__devices = []

    def add(self, deviceItem):
        self.__devices.append(deviceItem)

    def getCount(self):
        return len(self.__devices)

    def getByIdx(self, idx):
        if idx < 0 or idx >= self.getCount():
            return None
        return self.__devices[idx]

    def getById(self, id):
        for item in self.__devices:
            if (item.getId() == id):
                return item
        return None


class DeviceMgr(metaclass=ABCMeta):
    "设备基类"

    @abstractmethod
    def enumerate(self):
        "枚举设备列表"
        pass

    @abstractmethod
    def active(self, deviceId):
        "激活要使用的设备"
        pass

    @abstractmethod
    def getCurDevice(self):
        "获取当前激活设备ID"
        pass


class SpeakerMgr(DeviceMgr):
    "扬声器设备管理类"

    def __init__(self):
        self.__curDeviceId = None

    def enumerate(self):
        "枚举设备列表"
        devices = DeviceList()
        devices.add(DeviceItem("xxxxx", "Realtek High Definition Audio", DeviceType.TypeSpeaker))
        devices.add(DeviceItem("ooooo", "Nvidia High Definition Audio", DeviceType.TypeSpeaker, True))
        return devices

    def active(self, deviceId):
        "激活指定设备为当前设备"
        self.__curDeviceId = deviceId

    def getCurDeviceId(self):
        return self.__curDeviceId


class Deviceutil:
    "设备工具类"

    def __init__(self):
        self.__mgrs = {}
        self.__mgrs[DeviceType.TypeSpeaker] = SpeakerMgr()
        # 其他设备添加类似

    def __getDeviceMgr(self, type):
        "获取同类型的管理器"
        return self.__mgrs[type]

    def getDeviceList(self, type):
        "获取同类型的所有device"
        return self.__getDeviceMgr(type).enumerate()

    def active(self, type, deviceId):
        self.__getDeviceMgr(type).activate(deviceId)

    def getCurDeviceId(self, type):
        return self.__getDeviceMgr(type).getCurDeviceId()


def testDevices():
    deviceUtil = DeviceUtil()
    deviceList = deviceUtil.getDeviceList(DeviceType.TypeSpeaker)
    print("麦克风设备列表:")
    if devicelist.getCount() > 0:
        # 设置第一个设备为要用的设备
        deviceUtil.active(DeviceType.TypeSpeaker, deviceList.getByIdx(0).getId())
    for idx in range(0, deviceList.getCount()):
        device = deviceList.getByIdx(idx)
        print(device)
    print("当前使用的设备:" +
          deviceList.getById(deviceUtil.getCurDeviceId(DeviceType.TypeSpeaker)).getName())
This post is licensed under CC BY 4.0 by the author.

Python-常用装饰器

设计模式-克隆模式