用程序来模拟生活
模拟代码:
class HouseInfo:
"""租房为例房源信息"""
def __init__(self, area, price, has_window, has_bathroom, has_kitchen, address, owner):
self.__area = area
self.__price = price
self.__has_window = has_window
self.__has_bathroom = has_bathroom
self.__has_kitchen = has_kitchen
self.__address = address
self.__owner = owner
def get_address(self):
return self.__address
def get_owner_name(self):
return self.__owner.get_name()
def show_info(self, is_show_owner=True):
print('面积:' + str(self.__area) + '平方米',
'价格:' + str(self.__price) + '元',
'窗户:' + ('有' if self.__has_window else'没有'),
'厨房:' + ('有' if self.__has_kitchen else'没有'),
'地址:' + self.__address,
'房东:' + self.__owner.get_name() if is_show_owner else ''
)
class HousingAgency:
"""中介"""
def __init__(self, name):
self.__house_infos = []
self.__name = name
def get_name(self):
return self.__name
def add_house_info(self, house_info):
self.__house_infos.append(house_info)
def remove_house_info(self, house_info):
if house_info in self.__house_infos:
self.__house_infos.remove(house_info)
def get_search_condition(self, description):
"""这里有个将用户描述的信息转换称搜索条件的逻辑 为节省篇幅这里按照原样输出"""
return description
def get_match_info(self, search_condition):
"""根据房源信息的各个属性查找最匹配的信息"""
"""为节省篇幅这里略去匹配的过程, 全部输出"""
print(self.get_name(), '为你找到最合适的房源:')
for info in self.__house_infos:
info.show_info()
return self.__house_infos
def sign_contract(self, house_info, period):
"""与房东签订协议"""
print(self.get_name(), '与房东', house_info.get_owner_name(), '签订',
house_info.get_address(), '的房子的租合同,租期', period, '年。合同内',
self.get_name(), '有权对其进行使用和转租'
)
def sign_contracts(self, period):
for info in self.__house_infos:
self.sign_contract(info, period)
class HouseOwner:
"""房东"""
def __init__(self, name):
self.__name = name
self.__house_info = None
def get_name(self):
return self.__name
def set_house_info(self, address, area, price, has_window, bathroom, kitchen):
self.__house_info = HouseInfo(address=address, area=area, price=price, has_window=has_window,
has_bathroom=bathroom, has_kitchen=kitchen, owner=self)
def publish_house_info(self, agency):
agency.add_house_info(self.__house_info)
print(self.get_name() + '在', agency.get_name(), '发布房源出租信息:' )
self.__house_info.show_info()
class Customer:
"""用户,租房的贫下中农"""
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
def find_house(self, description, agency):
print('我是' + self.get_name() + ',我想要找个"' + description + '"的房子')
return agency.get_match_info(agency.get_search_condition)
def see_house(self, house_infos):
"""去看房子 省略看房的过程"""
size = len(house_infos)
return house_infos[size-1]
def sign_contract(self, house_info, agency, period):
"""与中介签订协议"""
print(self.get_name(), "与中介", agency.get_name(), '签订', house_info.get_address(),
'的房子的租合同,租期' + str(period), '年。合同期内', self.__name, '有权对其使用')
def test_renting():
my_house = HousingAgency('房极客')
zhang_san = HouseOwner('张三')
zhang_san.set_house_info(address='深圳湾', area=20, price=2000, has_window=1, bathroom=1, kitchen=1)
zhang_san.publish_house_info(my_house)
li_si = HouseOwner('李四')
li_si.set_house_info(address='观海台', area=30, price=2500, has_window=2, bathroom=3, kitchen=1)
li_si.publish_house_info(my_house)
wang_wu = HouseOwner('王五')
wang_wu.set_house_info(address='蔚蓝海岸城', area=10, price=2500, has_window=2, bathroom=3, kitchen=1)
wang_wu.publish_house_info(my_house)
my_house.sign_contracts(3)
tony = Customer('tony')
house_infos = tony.find_house('18平米左右,有独立卫生间,价格在2000左右', my_house)
appropriate_house = tony.see_house(house_infos)
tony.sign_contract(appropriate_house, my_house, 1)
if __name__ == '__main__':
test_renting()
什么是中介模式
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地进行交互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
中介模式的设计思想
从上述代码情节中我们知道,Tony找房子不需要与房东直接联系,他只需要与中介进行交互,一切都可以通过中介完成。
在很多系统中,多类很多相互耦合,形成网状结构。中介模式就是将这种网状分离。
代码框架
代码:
class InteractiveObject:
"""进行交互的对象"""
pass
class InteractiveObjectImplA:
pass
class InteractiveObjectImplB:
pass
class Meditor:
"""中介类"""
def __init__(self):
self.__interactive_objA = InteractiveObjectImplA()
self.__interactive_objB = InteractiveObjectImplB()
def interactive(self):
"""进行交互操作"""
# 通过self.__interactive_objA和self.__interactive_objB完成相应的交互操作
pass
Mediator就是中介类,用来协调对象间的相互交互,例如HousingAgency。中介类可以多个具体实现类,类如MediatorImplA和MediatorImplB。InteractiveObject是要进行交互的对象,例如HouseOwner和Customer。InteractiveObject可以是互不相干多个类的对象,也可以通过继承的关系相似类。
模型说明
设计要点:
中介模式主要一下三个角色,在设计中介模式时要找到并区分这些角色:
1.交互对象(interactiveObject),要进行交互的一系列对象。
2.中介者,负责协调各个对象之间的交互。
3.具体中介者:中介的具体实现。
中介模式的优缺点
优点
1.Mediator将原本分布多个对象间的行为聚集在一起,作为一个独立的概念并将其封装在一个对象中,简化类对象之间的交互。
2.将多个调用者与多个实现者之间多对多的交互关系,转换为一对多的交互关系,一对多的交互关系更易于理解、维护、扩展,大大减少类多个对象间的相互交叉引用的情况。
缺点
1.中介者承接类所有的交互逻辑,交互的复杂度转变成类中介者的复杂度,中介者类会变的越来越庞大和复杂,以至于难以维护。
2.中介者出现问题会导致多个使用者同时出现问题。
实战应用
代码:
from enum import Enum
class Device(Enum):
"""设备类别"""
type_speaker = 1
type_microphone = 2
type_camera = 3
class DeviceItem:
"""设备选项"""
def __init__(self, id, name, type, is_default=False):
self.__id = id
self.__name = name
self.__type = type
self.__is_default = is_default
def __str__(self):
return 'type:' + str(self.__type) + 'id:' + str(self.__id) + 'name:' + str(self.__name) \
+ 'is_default:' + str(self.__is_default)
def get_id(self):
return self.__id
def get_name(self):
return self.__name
def get_type(self):
return self.__type
def is_default(self):
return self.__is_default
class DeviceList:
"""设备列表"""
def __init__(self):
self.__devices = []
def add(self, device_item):
self.__devices.append(device_item)
def get_count(self):
return len(self.__devices)
def get_by_idx(self, idx):
if idx < 0 or idx >= self.get_count():
return None
return self.__devices[idx]
def get_by_id(self, id):
for itme in self.__devices:
if itme.get_id() == id:
return itme
return None
class DeviceMgr:
def enumerate(self):
"""枚举设备列表 在程序初始化时,有设备插拔时都重新获取列表"""
pass
def active(self, device_id):
"""选择要使用的设备"""
pass
def get_cur_device_id(self):
"""获取当前正在使用的设备ID"""
pass
class SpeakerMgr(DeviceMgr):
"""扬声器设备管理器"""
def __init__(self):
self.__cur_device_id = None
def enumerate(self):
"""枚举列表"""
devices = DeviceList()
devices.add(DeviceItem('123-678-987', 'Realtek', Device.type_speaker))
devices.add(DeviceItem('785-673-322', 'NVIDIA', Device.type_speaker, True))
return devices
def active(self, device_id):
"""激活指定的设备作为当前的要用的设备"""
self.__cur_device_id = device_id
def get_cur_device_id(self):
return self.__cur_device_id
class DeviceUtil:
"""设备工具类"""
def __init__(self):
self.__mgrs = {}
self.__mgrs[Device.type_speaker] = SpeakerMgr()
"""为节省篇幅,Microphone和CameraMgr不再实现"""
def __get_device_mgr(self, device_type):
return self.__mgrs[device_type]
def get_device_list(self, device_type):
return self.__get_device_mgr(device_type).enumerate()
def active(self, device_type, device_id):
self.__get_device_mgr(device_type).active(device_id)
def get_cur_device_id(self, device_type):
return self.__get_device_mgr(device_type).get_cur_device_id()
def test_devices():
device_util = DeviceUtil()
device_list = device_util.get_device_list(Device.type_speaker)
if device_list.get_count() > 0:
device_util.active(Device.type_speaker, device_list.get_by_idx(0).get_id())
for idx in range(device_list.get_count()):
device = device_list.get_by_idx(idx)
print(device)
print('当前使用的设备:' + device_list.get_by_id(device_util.get_cur_device_id(Device.type_speaker)).get_name())
if __name__ == '__main__':
test_devices()
应用场景
1.一组对象以定义良好但是复杂的方式进行通信,产生相互依赖关系结构混乱且难以理解。
2.一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3.想通过一个中间类来封装多个类的行为,同时又不想生成太多的子类。