用程序来模拟生活
模拟代码:
class HouseInfo:"""租房为例房源信息"""def __init__(self, area, price, has_window, has_bathroom, has_kitchen, address, owner):self.__area = areaself.__price = priceself.__has_window = has_windowself.__has_bathroom = has_bathroomself.__has_kitchen = has_kitchenself.__address = addressself.__owner = ownerdef get_address(self):return self.__addressdef 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 = namedef get_name(self):return self.__namedef 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 descriptiondef get_match_info(self, search_condition):"""根据房源信息的各个属性查找最匹配的信息""""""为节省篇幅这里略去匹配的过程, 全部输出"""print(self.get_name(), '为你找到最合适的房源:')for info in self.__house_infos:info.show_info()return self.__house_infosdef 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 = nameself.__house_info = Nonedef get_name(self):return self.__namedef 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 = namedef get_name(self):return self.__namedef 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:"""进行交互的对象"""passclass InteractiveObjectImplA:passclass InteractiveObjectImplB:passclass 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 Enumclass Device(Enum):"""设备类别"""type_speaker = 1type_microphone = 2type_camera = 3class DeviceItem:"""设备选项"""def __init__(self, id, name, type, is_default=False):self.__id = idself.__name = nameself.__type = typeself.__is_default = is_defaultdef __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.__iddef get_name(self):return self.__namedef get_type(self):return self.__typedef is_default(self):return self.__is_defaultclass 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 Nonereturn self.__devices[idx]def get_by_id(self, id):for itme in self.__devices:if itme.get_id() == id:return itmereturn Noneclass DeviceMgr:def enumerate(self):"""枚举设备列表 在程序初始化时,有设备插拔时都重新获取列表"""passdef active(self, device_id):"""选择要使用的设备"""passdef get_cur_device_id(self):"""获取当前正在使用的设备ID"""passclass SpeakerMgr(DeviceMgr):"""扬声器设备管理器"""def __init__(self):self.__cur_device_id = Nonedef 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 devicesdef active(self, device_id):"""激活指定的设备作为当前的要用的设备"""self.__cur_device_id = device_iddef get_cur_device_id(self):return self.__cur_device_idclass 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.想通过一个中间类来封装多个类的行为,同时又不想生成太多的子类。
