源码地址: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. 二进制转化为十进制Java实现

    二进制转化为十进制 ①按权展开方法Java实现 /* * 按权展开法 */ public static double BinToTen1(String binary) { //查找该二进制是否存在小数 ...

  2. 利用Python做绝地科学家(外挂篇)

    i春秋作家:奶权 前言  玩吃鸡时间长的鸡友们 应该都知道现在的游戏环境非常差 特别在高端局 神仙满天飞 搞得很多普通玩家非常没有游戏体验  因为吃鸡的火爆 衍生出了一条巨大的外挂利益链 导致市面上出 ...

  3. 【spring cloud】服务启动后正常,但是无法上线,一直处于down状态

    spring cloud eureka 如果出现某个应用实例 down(1), 说明 spring admin 健康检测没有通过导致 eureka 注册中心不会把这个实例从列表中删除掉. 这样所有使用 ...

  4. mongodb初始化并使用node.js实现mongodb操作封装

    mongodb的下载只要在https://www.mongodb.com/网站就能够下载 下载后安装只用一直点next就可以,注意最好使用默认路径安装到C盘,然后在任意位置建立一个文件夹用于储存你的数 ...

  5. 10-03 Java 包的概述和讲解

    带包的编译和运行 A:手动式 a:编写一个带包的java文件. b:通过javac命令编译该java文件. c:手动创建包名. d:把b步骤的class文件放到c步骤的最底层包 e:回到和包根目录在同 ...

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

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

  7. 一口一口吃掉Volley(二)

    欢迎访问我的个人博客转发请注明出处:http://www.wensibo.top/2017/02/17/一口一口吃掉Volley(二)/ 相信看了第一篇教程之后,你应该会对Volley有一个初步的了解 ...

  8. 全网最详细的Windows里下载与安装Sublime Text *(图文详解)

    不多说,直接上干货! 前言 这是代码编程软件,可以性感编程自己代码,有着非常丰富的插件,界面整洁清爽.第一次使用可能不习惯,当你使用一段时间之后,你就会爱上它. 下载与安装 1.下载:目前官方的正式版 ...

  9. 制作windows服务

    1.下载winsw-1.8-bin.exe并更名: 2.配置winsw-1.8-bin.exe同上名<?xml version="1.0" encoding="UT ...

  10. vue修改对象属性值视图上没有更新

    data(){ return { obj:{ name:' ' } } } 方法一: this.$set(this.obj, 'name', '新的值'); 方法二; Vue.set(vm.obj, ...