源码地址:https://github.com/weilanhanf/PythonDesignPatterns

说明:

面向对象设计中鼓励将行为分不到各个对象中,这种分布可能会导致对象间有许多连接。最坏的情况下,每一个对象都知道其他所有对象,这就非常不符合设计模式原则了。因为单一指责原则要求我们应该尽量将对象细化,使其只负责单一的职责。并且当大量对象相互连接交织在一起的时候,对系统行为的改动将变得十分困难。当连接关系十分复杂的时候,系统也将面临失控的危险。举例:在同一个城市中,有许多买房和卖房的人组成的一个庞大群体,双方都想找到合适的卖家或者买家。如果买卖家双方直接沟通,可想而知无论对于卖家还是买家想称心如意都是一件十分困难的事。并且当房源信息发生变化的时候,也十分麻烦。由此就有了中介公司,中介公司通过收集买卖双方人的信息,来通知双方需要的信息,这样事情就好办的多了。在软件结构中引入中介者这个角色,可以避免相互交互的对象间的紧耦合引用关系,解决系统交互过程中存在的复杂和低效问题。

中介者模式的定义为:用一个中介对象封装一系列的对象交互。中介者使各对象不需要显式地互相作用,从而使其耦合松散,并可以独立地改变它们之间的交互。很重要的一点就是中介者模式可以使得对象之间的关系数量急剧减少。

结构:

抽象中介者,具体中介者,抽象同事类,具体同事类。

实例:

有一个手机仓储管理系统,使用者有三方:销售、仓库管理员、采购。需求是:销售一旦达成订单,销售人员会通过系统的销售子系统部分通知仓储子系统,仓储子系统会将可出仓手机数量减少,同时通知采购管理子系统当前销售订单;仓储子系统的库存到达阈值以下,会通知销售子系统和采购子系统,并督促采购子系统采购;采购完成后,采购人员会把采购信息填入采购子系统,采购子系统会通知销售子系统采购完成,并通知仓库子系统增加库存。从需求描述来看,每个子系统都和其它子系统有所交流,在设计系统时,如果直接在一个子系统中集成对另两个子系统的操作,一是耦合太大,二是不易扩展。为解决这类问题,我们需要引入一个新的角色-中介者-来将“网状结构”精简为“星形结构”。(为充分说明设计模式,某些系统细节暂时不考虑,例如:仓库满了怎么办该怎么设计。类似业务性的内容暂时不考虑)

#构造三个子系统,即三个类(在中介者模式中,这些类叫做同事类)
class colleague():
mediator = None
def __init__(self,mediator):
self.mediator = mediator
class purchaseColleague(colleague):
def buyStuff(self,num):
print("PURCHASE:Bought %s"%num)
self.mediator.execute("buy",num)
def getNotice(self,content):
print("PURCHASE:Get Notice--%s"%content)
class warehouseColleague(colleague):
total=0
threshold=100
def setThreshold(self,threshold):#设置阈值
self.threshold=threshold
def isEnough(self):
if self.total<self.threshold:
print("WAREHOUSE:Warning...Stock is low... ")
self.mediator.execute("warning",self.total)
return False
else:
return True
def inc(self,num):
self.total+=num
print("WAREHOUSE:Increase %s"%num)
self.mediator.execute("increase",num)
self.isEnough()
def dec(self,num):
if num>self.total:
print("WAREHOUSE:Error...Stock is not enough")
else:
self.total-=num
print("WAREHOUSE:Decrease %s"%num)
self.mediator.execute("decrease",num)
self.isEnough()
class salesColleague(colleague):
def sellStuff(self,num):
print("SALES:Sell %s"%num)
self.mediator.execute("sell",num)
def getNotice(self, content):
print("SALES:Get Notice--%s" % content) #当各个类在初始时都会指定一个中介者,而各个类在有变动时,也会通知中介者,由中介者协调各个类的操作。
#中介者实现
class abstractMediator():
purchase=""
sales=""
warehouse=""
def setPurchase(self,purchase):
self.purchase=purchase
def setWarehouse(self,warehouse):
self.warehouse=warehouse
def setSales(self,sales):
self.sales=sales
def execute(self,content,num):
pass
class stockMediator(abstractMediator):
def execute(self,content,num):
print("MEDIATOR:Get Info--%s"%content)
if content=="buy":
self.warehouse.inc(num)
self.sales.getNotice("Bought %s"%num)
elif content=="increase":
self.sales.getNotice("Inc %s"%num)
self.purchase.getNotice("Inc %s"%num)
elif content=="decrease":
self.sales.getNotice("Dec %s"%num)
self.purchase.getNotice("Dec %s"%num)
elif content=="warning":
self.sales.getNotice("Stock is low.%s Left."%num)
self.purchase.getNotice("Stock is low. Please Buy More!!! %s Left"%num)
elif content=="sell":
self.warehouse.dec(num)
self.purchase.getNotice("Sold %s"%num)
else:
pass #中介者模式中的execute是最重要的方法,它根据同事类传递的信息,直接协调各个同事的工作。
#在场景类中,设置仓储阈值为200,先采购300,再卖出120,实现如下
if __name__=="__main__":
mobile_mediator=stockMediator()#先配置
mobile_purchase=purchaseColleague(mobile_mediator)
mobile_warehouse=warehouseColleague(mobile_mediator)
mobile_sales=salesColleague(mobile_mediator)
mobile_mediator.setPurchase(mobile_purchase)
mobile_mediator.setWarehouse(mobile_warehouse)
mobile_mediator.setSales(mobile_sales) mobile_warehouse.setThreshold(200)
mobile_purchase.buyStuff(300)
mobile_sales.sellStuff(120)

打印结果:

PURCHASE:Bought 300
MEDIATOR:Get Info--buy
WAREHOUSE:Increase 300
MEDIATOR:Get Info--increase
SALES:Get Notice--Inc 300
PURCHASE:Get Notice--Inc 300
SALES:Get Notice--Bought 300
SALES:Sell 120
MEDIATOR:Get Info--sell
WAREHOUSE:Decrease 120
MEDIATOR:Get Info--decrease
SALES:Get Notice--Dec 120
PURCHASE:Get Notice--Dec 120
WAREHOUSE:Warning...Stock is low...
MEDIATOR:Get Info--warning
SALES:Get Notice--Stock is low.180 Left.
PURCHASE:Get Notice--Stock is low. Please Buy More!!! 180 Left
PURCHASE:Get Notice--Sold 120

优点:

简化了对象之间的交互。减少子类的生成。

缺点:

在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

适用场景:

用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。设计类图时,出现了网状结构时,可以考虑将类图设计成星型结构,这样就可以使用中介者模式了。如机场调度系统(多个跑道、飞机、指挥塔之间的调度)、路由系统;著名的MVC框架中,其中的C(Controller)就是M(Model)和V(View)的中介者。

python-中介者模式的更多相关文章

  1. 设计模式-行为型模式,python 中介者模式

    中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护.中介者模式属于行 ...

  2. 大话设计模式Python实现-中介者模式

    中介者模式(Mediator Pattern):用一个对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互. 下面是一个中介者模式的demo ...

  3. [Python设计模式] 第25章 联合国维护世界和平——中介者模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目背景 联合国在世界上就是中介者的角色,各国之间的关系复杂,类似不同的对象和对 ...

  4. python 设计模式之中介者模式

    #先啰嗦一下 至少半个多月的样子没写博客了,月初去了趟黄山,赏了美景,自然没时间也没条件敲博客了,一个多星期就这么过去了.返回深圳后,工作积压了一堆,然后白天就马不停蹄的忙工作,晚上回家伺候小娃,又想 ...

  5. 23种设计模式--中介者模式-Mediator Pattern

    一.中介者模式的介绍     中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...

  6. MediatorPattern(中介者模式)

    /** * 中介者模式 * @author TMAC-J * 研究了这么多设计模式,觉得无非就是几点: * 1.若两个类有耦合关系,设立一个中间类,处理两个类的关系,把两个类的耦合降低 * 2.面向接 ...

  7. C#设计模式-中介者模式

    在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 一. 中介者(Mediator)模式 从 ...

  8. php实现设计模式之 中介者模式

    <?php /* * 中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ /* * 以一个同学qq群为例说明, ...

  9. 轻松掌握:JavaScript代理模式、中介者模式

    代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...

  10. java设计模式之中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...

随机推荐

  1. 修改ssh远程默认端口

    修改ssh远程默认端口 Linuxssh端口修改 1. 修改ssh配置文件 [root@distzabbix ~]# vim /etc/ssh/sshd_config 找到第17行附近#Port 22 ...

  2. Doxygen的使用,配置及实例

    Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,可以从一套归档源文件开始,生成文档 下载Doxygen + Graphviz Doxygen可以生成动态文档 Graphviz ...

  3. java实现office文件预览

    不知觉就过了这个久了,继上篇java实现文件上传下载后,今天给大家分享一篇java实现的对office文件预览功能. 相信大家在平常的项目中会遇到需要对文件实现预览功能,这里不用下载节省很多事.大家请 ...

  4. POJ 2601

    #include<iostream> #include<iomanip> #include<stdio.h> using namespace std; int ma ...

  5. 在Ubuntu 16.04上利用Jexus+.Net Core+Linux版SQL Server部署ZKEACMS.Core

    百度传课视频地址:https://chuanke.baidu.com/v5849090-223278-1498090.html 一.SQL Server on Linux的安装 官方文档:https: ...

  6. Identity Server4学习系列四之用户名密码获得访问令牌

    1.简介 Identity Server4支持用户名密码模式,允许调用客户端使用用户名密码来获得访问Api资源(遵循Auth 2.0协议)的Access Token,MS可能考虑兼容老的系统,实现了这 ...

  7. C# 多线程学习系列一

    一.Windows线程的由来  关于操作系统的一些知识 (1).单个"工作线程"的问题 早期的Windows没有线程的概念,整个系统只有一个"工作线程",上面同 ...

  8. MyBatis中如何一次执行多条语句(使用mysql数据库)

    解决办法不外乎有三个:1.多条sql分批执行:2.存储过程或函数调用:3.sql批量执行. MyBatis中如何一次执行多条语句(使用mysql数据库): 1.修改数据库连接参数加上allowMult ...

  9. 浏览器中F5和CTRL F5的行为区别及如何强制更新资源

    一.浏览器中F5和CTRL F5的行为区别 我们直接来看效果,下面是我打开qq网页,分别使用F5和CTRL F5,我们来看区别. F5: CTRL F5: 区别: 首先直观上的区别是CTRL F5明显 ...

  10. Redis随笔(六)RESP的协议规范

    1.官网文档 https://redis.io/topics/protocol http://www.redis.cn/topics/protocol.html 2.协议介绍 redis协议规范(Re ...