用程序来模拟生活

模拟代码:

  1. class HouseInfo:
  2. """租房为例房源信息"""
  3. def __init__(self, area, price, has_window, has_bathroom, has_kitchen, address, owner):
  4. self.__area = area
  5. self.__price = price
  6. self.__has_window = has_window
  7. self.__has_bathroom = has_bathroom
  8. self.__has_kitchen = has_kitchen
  9. self.__address = address
  10. self.__owner = owner
  11. def get_address(self):
  12. return self.__address
  13. def get_owner_name(self):
  14. return self.__owner.get_name()
  15. def show_info(self, is_show_owner=True):
  16. print('面积:' + str(self.__area) + '平方米',
  17. '价格:' + str(self.__price) + '元',
  18. '窗户:' + ('有' if self.__has_window else'没有'),
  19. '厨房:' + ('有' if self.__has_kitchen else'没有'),
  20. '地址:' + self.__address,
  21. '房东:' + self.__owner.get_name() if is_show_owner else ''
  22. )
  23. class HousingAgency:
  24. """中介"""
  25. def __init__(self, name):
  26. self.__house_infos = []
  27. self.__name = name
  28. def get_name(self):
  29. return self.__name
  30. def add_house_info(self, house_info):
  31. self.__house_infos.append(house_info)
  32. def remove_house_info(self, house_info):
  33. if house_info in self.__house_infos:
  34. self.__house_infos.remove(house_info)
  35. def get_search_condition(self, description):
  36. """这里有个将用户描述的信息转换称搜索条件的逻辑 为节省篇幅这里按照原样输出"""
  37. return description
  38. def get_match_info(self, search_condition):
  39. """根据房源信息的各个属性查找最匹配的信息"""
  40. """为节省篇幅这里略去匹配的过程, 全部输出"""
  41. print(self.get_name(), '为你找到最合适的房源:')
  42. for info in self.__house_infos:
  43. info.show_info()
  44. return self.__house_infos
  45. def sign_contract(self, house_info, period):
  46. """与房东签订协议"""
  47. print(self.get_name(), '与房东', house_info.get_owner_name(), '签订',
  48. house_info.get_address(), '的房子的租合同,租期', period, '年。合同内',
  49. self.get_name(), '有权对其进行使用和转租'
  50. )
  51. def sign_contracts(self, period):
  52. for info in self.__house_infos:
  53. self.sign_contract(info, period)
  54. class HouseOwner:
  55. """房东"""
  56. def __init__(self, name):
  57. self.__name = name
  58. self.__house_info = None
  59. def get_name(self):
  60. return self.__name
  61. def set_house_info(self, address, area, price, has_window, bathroom, kitchen):
  62. self.__house_info = HouseInfo(address=address, area=area, price=price, has_window=has_window,
  63. has_bathroom=bathroom, has_kitchen=kitchen, owner=self)
  64. def publish_house_info(self, agency):
  65. agency.add_house_info(self.__house_info)
  66. print(self.get_name() + '在', agency.get_name(), '发布房源出租信息:' )
  67. self.__house_info.show_info()
  68. class Customer:
  69. """用户,租房的贫下中农"""
  70. def __init__(self, name):
  71. self.__name = name
  72. def get_name(self):
  73. return self.__name
  74. def find_house(self, description, agency):
  75. print('我是' + self.get_name() + ',我想要找个"' + description + '"的房子')
  76. return agency.get_match_info(agency.get_search_condition)
  77. def see_house(self, house_infos):
  78. """去看房子 省略看房的过程"""
  79. size = len(house_infos)
  80. return house_infos[size-1]
  81. def sign_contract(self, house_info, agency, period):
  82. """与中介签订协议"""
  83. print(self.get_name(), "与中介", agency.get_name(), '签订', house_info.get_address(),
  84. '的房子的租合同,租期' + str(period), '年。合同期内', self.__name, '有权对其使用')
  85. def test_renting():
  86. my_house = HousingAgency('房极客')
  87. zhang_san = HouseOwner('张三')
  88. zhang_san.set_house_info(address='深圳湾', area=20, price=2000, has_window=1, bathroom=1, kitchen=1)
  89. zhang_san.publish_house_info(my_house)
  90. li_si = HouseOwner('李四')
  91. li_si.set_house_info(address='观海台', area=30, price=2500, has_window=2, bathroom=3, kitchen=1)
  92. li_si.publish_house_info(my_house)
  93. wang_wu = HouseOwner('王五')
  94. wang_wu.set_house_info(address='蔚蓝海岸城', area=10, price=2500, has_window=2, bathroom=3, kitchen=1)
  95. wang_wu.publish_house_info(my_house)
  96. my_house.sign_contracts(3)
  97. tony = Customer('tony')
  98. house_infos = tony.find_house('18平米左右,有独立卫生间,价格在2000左右', my_house)
  99. appropriate_house = tony.see_house(house_infos)
  100. tony.sign_contract(appropriate_house, my_house, 1)
  101. if __name__ == '__main__':
  102. test_renting()

什么是中介模式

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地进行交互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。

中介模式的设计思想

从上述代码情节中我们知道,Tony找房子不需要与房东直接联系,他只需要与中介进行交互,一切都可以通过中介完成。
在很多系统中,多类很多相互耦合,形成网状结构。中介模式就是将这种网状分离。

代码框架

代码:

  1. class InteractiveObject:
  2. """进行交互的对象"""
  3. pass
  4. class InteractiveObjectImplA:
  5. pass
  6. class InteractiveObjectImplB:
  7. pass
  8. class Meditor:
  9. """中介类"""
  10. def __init__(self):
  11. self.__interactive_objA = InteractiveObjectImplA()
  12. self.__interactive_objB = InteractiveObjectImplB()
  13. def interactive(self):
  14. """进行交互操作"""
  15. # 通过self.__interactive_objA和self.__interactive_objB完成相应的交互操作
  16. pass

Mediator就是中介类,用来协调对象间的相互交互,例如HousingAgency。中介类可以多个具体实现类,类如MediatorImplA和MediatorImplB。InteractiveObject是要进行交互的对象,例如HouseOwner和Customer。InteractiveObject可以是互不相干多个类的对象,也可以通过继承的关系相似类。

模型说明

设计要点:

中介模式主要一下三个角色,在设计中介模式时要找到并区分这些角色:
1.交互对象(interactiveObject),要进行交互的一系列对象。
2.中介者,负责协调各个对象之间的交互。
3.具体中介者:中介的具体实现。

中介模式的优缺点

优点

1.Mediator将原本分布多个对象间的行为聚集在一起,作为一个独立的概念并将其封装在一个对象中,简化类对象之间的交互。
2.将多个调用者与多个实现者之间多对多的交互关系,转换为一对多的交互关系,一对多的交互关系更易于理解、维护、扩展,大大减少类多个对象间的相互交叉引用的情况。

缺点

1.中介者承接类所有的交互逻辑,交互的复杂度转变成类中介者的复杂度,中介者类会变的越来越庞大和复杂,以至于难以维护。
2.中介者出现问题会导致多个使用者同时出现问题。

实战应用

代码:

  1. from enum import Enum
  2. class Device(Enum):
  3. """设备类别"""
  4. type_speaker = 1
  5. type_microphone = 2
  6. type_camera = 3
  7. class DeviceItem:
  8. """设备选项"""
  9. def __init__(self, id, name, type, is_default=False):
  10. self.__id = id
  11. self.__name = name
  12. self.__type = type
  13. self.__is_default = is_default
  14. def __str__(self):
  15. return 'type:' + str(self.__type) + 'id:' + str(self.__id) + 'name:' + str(self.__name) \
  16. + 'is_default:' + str(self.__is_default)
  17. def get_id(self):
  18. return self.__id
  19. def get_name(self):
  20. return self.__name
  21. def get_type(self):
  22. return self.__type
  23. def is_default(self):
  24. return self.__is_default
  25. class DeviceList:
  26. """设备列表"""
  27. def __init__(self):
  28. self.__devices = []
  29. def add(self, device_item):
  30. self.__devices.append(device_item)
  31. def get_count(self):
  32. return len(self.__devices)
  33. def get_by_idx(self, idx):
  34. if idx < 0 or idx >= self.get_count():
  35. return None
  36. return self.__devices[idx]
  37. def get_by_id(self, id):
  38. for itme in self.__devices:
  39. if itme.get_id() == id:
  40. return itme
  41. return None
  42. class DeviceMgr:
  43. def enumerate(self):
  44. """枚举设备列表 在程序初始化时,有设备插拔时都重新获取列表"""
  45. pass
  46. def active(self, device_id):
  47. """选择要使用的设备"""
  48. pass
  49. def get_cur_device_id(self):
  50. """获取当前正在使用的设备ID"""
  51. pass
  52. class SpeakerMgr(DeviceMgr):
  53. """扬声器设备管理器"""
  54. def __init__(self):
  55. self.__cur_device_id = None
  56. def enumerate(self):
  57. """枚举列表"""
  58. devices = DeviceList()
  59. devices.add(DeviceItem('123-678-987', 'Realtek', Device.type_speaker))
  60. devices.add(DeviceItem('785-673-322', 'NVIDIA', Device.type_speaker, True))
  61. return devices
  62. def active(self, device_id):
  63. """激活指定的设备作为当前的要用的设备"""
  64. self.__cur_device_id = device_id
  65. def get_cur_device_id(self):
  66. return self.__cur_device_id
  67. class DeviceUtil:
  68. """设备工具类"""
  69. def __init__(self):
  70. self.__mgrs = {}
  71. self.__mgrs[Device.type_speaker] = SpeakerMgr()
  72. """为节省篇幅,Microphone和CameraMgr不再实现"""
  73. def __get_device_mgr(self, device_type):
  74. return self.__mgrs[device_type]
  75. def get_device_list(self, device_type):
  76. return self.__get_device_mgr(device_type).enumerate()
  77. def active(self, device_type, device_id):
  78. self.__get_device_mgr(device_type).active(device_id)
  79. def get_cur_device_id(self, device_type):
  80. return self.__get_device_mgr(device_type).get_cur_device_id()
  81. def test_devices():
  82. device_util = DeviceUtil()
  83. device_list = device_util.get_device_list(Device.type_speaker)
  84. if device_list.get_count() > 0:
  85. device_util.active(Device.type_speaker, device_list.get_by_idx(0).get_id())
  86. for idx in range(device_list.get_count()):
  87. device = device_list.get_by_idx(idx)
  88. print(device)
  89. print('当前使用的设备:' + device_list.get_by_id(device_util.get_cur_device_id(Device.type_speaker)).get_name())
  90. if __name__ == '__main__':
  91. test_devices()

应用场景

1.一组对象以定义良好但是复杂的方式进行通信,产生相互依赖关系结构混乱且难以理解。
2.一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3.想通过一个中间类来封装多个类的行为,同时又不想生成太多的子类。