还记得我刚毕业的第一家公司是做b2c的,当时要做一个进销存系统,相信做过的人都应该清楚。拿最简单的进销存系统为例,其可分为采购管理、销售管理、和存货管理,三个模块相互依赖,假设现在公司为一家卖电脑的经销商:
1、销售情况
销售部门要反馈销售情况,畅销就多采购,滞销就不采购。
2、库存情况
即使是畅销产品,库存都有100台了,每天才卖出去1台,也不需要采购了!
库房有货,才能销售,空手套白狼是不行的。
库房的有容积限制的,不可有无限大,所以就有了清仓处理,需要停止采购,打拆销售。
3、督促采购
在特殊情况下,比如一个企业客户一次性购买100台,库存只有80台,这时需要催促采购。
实现代码如下:
<?php class Purchase{ public function buyComputer($number){ $stock = new Stock(); $sale = new Sale(); $saleStatus = $sale->getSaleStatus(); if($saleStatus>80){ echo "采购电脑".$number."台\n"; $stock->increase($number); }else{ $buyComputer = $number/2; echo "采购电脑".$buyComputer."台\n"; $stock->increase($buyComputer); } } public function refuseBuy(){ echo "不再采购电脑\n"; } } class Stock{ private static $computer_number = 100; public function increase($number){ self::$computer_number += $number; echo "库存数量为:".self::$computer_number."\n"; } public function decrease($number){ self::$computer_number -= $number; echo "库存数量为:".self::$computer_number."\n"; } public function getStockNumber(){ return self::$computer_number; } public function clearStock(){ $purchase = new Purchase(); $sale = new Sale(); echo "库存数量为:".self::$computer_number."\n"; //要求拆价销售 $sale->offSale(); //要求采购人员停止采购 $purchase->refuseBuy(); } } class Sale{ public function sellComputer($number){ $stock = new Stock(); $purchase = new Purchase(); if($stock->getStockNumber()<$number){ $purchase->buyComputer($number); } echo "销售电脑".$number."台\n"; $stock->decrease($number); } public function getSaleStatus(){ $saleStatus = mt_rand(0,100); echo "电脑的销售情况为:".$saleStatus."\n"; return $saleStatus; } public function offSale(){ $stock = new Stock(); echo "拆价销售电脑".$stock->getStockNumber()."台\n"; } } $purchase = new Purchase(); $purchase->buyComputer(100); $sale = new Sale(); $sale->sellComputer(1); $stock = new Stock(); $stock->clearStock(); ?> 运行结果: 电脑的销售情况为:70 采购电脑50台 库存数量为:150 销售电脑1台 库存数量为:149 库存数量为:149 拆价销售电脑149台 不再采购电脑 [Finished in 0.3s]
运行结果是我们所期望的,三个不同类型的参与者完成了各自的活动。但你有没有发现这三个类是彼此关联的?在之前的博客设计模式六原则中提到的迪米特法则认为“每个类只和朋友类交流”,这个朋友类并非越多越好,朋友类越多,耦合性越大,要想修改一个就得修改一片。何况这只是最简单的进销存,如果再加入物流管理,供应商管理,资产管理等等,那程序将会像蜘蛛网般。
现有一个助人为乐的中介者作为三个模块的交流核心,每个模块之间不再相互交流,要交流都通过中介者进行。每个模块只负责自己的业务逻辑,不属于自己的则丢给中介者处理,简化了各模块之间的耦合关系。类图如下:
修改代码如下:
<?php abstract class AbstractMediator { protected $purchase = null; protected $stock = null; protected $sale = null; public function __construct() { $this->purchase = new Purchase( $this ); $this->stock = new Stock( $this ); $this->sale = new Sale( $this ); } abstract public function execute(); } class Mediator extends AbstractMediator{ public function execute() { $args = func_get_args(); if ( !is_array( $args ) || empty( $args ) ) return; $method = $args[0]; unset( $args[0] ); call_user_func_array( array( $this, $method ), $args ); } //中介者 Mediator定义多个private方法,目的是处理各个对象之间的依赖关系。 private function buyComputer( $number ) { $saleStatus = $this->sale->getSaleStatus(); if ( $saleStatus<=80 ) { $number = $number/2; } echo "采购电脑".$number."台\n"; $this->stock->increase( $number ); } private function clearStock() { echo "库存数量为:".$this->stock->getStockNumber()."\n"; //要求拆价销售 $this->sale->offSale(); //要求采购人员停止采购 $this->purchase->refuseBuy(); } private function sellComputer( $number ) { if ( $this->stock->getStockNumber()<$number ) { $this->purchase->buyComputer( $number ); } echo "销售电脑".$number."台\n"; $this->stock->decrease( $number ); } private function offSale() { echo "拆价销售电脑".$this->stock->getStockNumber()."台\n"; } } abstract class AbstractColleague { protected $mediator = null; public function __construct( $mediator ) { $this->mediator = $mediator; } } class Purchase extends AbstractColleague{ public function buyComputer( $number ) { $this->mediator->execute( 'buyComputer', $number ); } public function refuseBuy() { echo "不再采购电脑\n"; } } class Stock extends AbstractColleague{ private static $computer_number = 100; public function increase( $number ) { self::$computer_number += $number; echo "库存数量为:".self::$computer_number."\n"; } public function decrease( $number ) { self::$computer_number -= $number; echo "库存数量为:".self::$computer_number."\n"; } public function getStockNumber() { return self::$computer_number; } public function clearStock() { $this->mediator->execute( 'clearStock' ); } } class Sale extends AbstractColleague{ public function sellComputer( $number ) { $this->mediator->execute( 'sellComputer', $number ); } public function getSaleStatus() { $saleStatus = mt_rand( 0, 100 ); echo "电脑的销售情况为:".$saleStatus."\n"; return $saleStatus; } public function offSale() { $this->mediator->execute( 'offSale' ); } } $mediator = new Mediator(); $purchase = new Purchase( $mediator ); $purchase->buyComputer( 100 ); $sale = new Sale( $mediator ); $sale->sellComputer( 1 ); $stock = new Stock( $mediator ); $stock->clearStock(); ?> 运行结果: 电脑的销售情况为:70 采购电脑50台 库存数量为:150 销售电脑1台 库存数量为:149 库存数量为:149 拆价销售电脑149台 不再采购电脑 [Finished in 0.3s]
加入中介者后,设计结构清晰了很多,而且类间的耦合性大大减少,代码质量也有了很大的提升。
中介者模式的定义
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显性地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介者模式由以下几部门组成:
1、Mediator 抽象中介者角色
抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
2、 Concrete Mediator 具体中介者角色
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
3、Colleague 同事角色
每一个同事角色都知道中介者角色,并且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。
中介者模式的优点
减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合
中介者模式的缺点
中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑也就越复杂。
中介者模式的实际应用(MVC)
相信大家都使用过MVC框架,其中的C(controller)就是一个中介者,叫做前端控制器(Front Controller),它的作用就是把M和V隔离开,协调M和V协同工作,把M运行的结果和V代表的视图融合成一个前端可以展示的页面,减少M和V的依赖关系。
中介者模式是一个非常好的封装模式,也是一个很容易被滥用的模式,一个对象依赖几个对象是再正常不过的事情,但是纯理论家就会要求使用中介者模式来封装这种依赖关系,这是非常危险的!因此在使用时请考虑中介者带来的膨胀问题。
相关推荐
**设计模式之中介者模式(Mediator Pattern)** 在软件工程中,设计模式是一种解决常见问题的经验总结,它提供了一种可复用的解决方案。中介者模式是行为设计模式之一,其主要目的是降低多个对象之间的复杂性,通过...
中介者模式(Mediator Pattern)是一种行为型设计模式,用于减少对象之间的直接相互依赖,使得对象间的交互通过一个中介者对象来进行协调。在中介者模式中,对象之间不再直接相互调用,而是通过中介者对象来传递消息...
**中介者模式(Mediator)详解** 在软件工程中,设计模式是一种被广泛采用的解决常见问题的经验总结,其中中介者模式是结构型设计模式的一种。它的主要目标是降低对象之间的耦合度,使得对象之间的关系更加清晰,...
**中介者模式(Mediator)**是一种设计模式,属于行为设计模式范畴,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。在软件工程中,中介者模式常...
标题和描述均提到了"C#面向对象设计模式纵横谈(17):(行为型模式) Mediator 中介者模式",这明确指向了一个特定的设计模式——中介者模式(Mediator Pattern),并且是在C#语言环境下的应用。下面将详细阐述这一设计...
咱们先来看下中介者模式(Mediator Pattern)的定义,它就是,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,这种模式又称为调停...
C#面向对象设计模式 (行为型模式) Mediator 中介者模式 视频讲座下载
**中介者模式(Mediator Pattern)**是一种行为设计模式,它定义了一个用来封装一系列对象交互的接口。在软件工程中,当多个对象之间存在复杂的相互依赖关系时,这种模式可以帮助我们降低系统的耦合度,使得各个对象...
**中介者模式(Mediator Pattern)**是一种行为设计模式,其主要目的是降低多个对象之间的通信复杂性,将这些对象的直接交互转化为与一个中心对象——中介者的交互。在C#中,中介者模式的应用能够有效地减少类之间的...
Java设计模式中的中介者模式(Mediator Pattern)是一种行为设计模式,它的主要目的是降低多个对象之间的耦合性,使得这些对象之间不必显式地互相引用,而是通过一个中介对象进行通信。这种模式使得对象间的交互更为...
中介者模式(Mediator Pattern)是一种行为设计模式,它允许对象之间通过中介者对象进行通信,从而避免对象之间的直接耦合。中介者模式将对象之间的复杂关系转化为中介者和对象之间的简单关系,从而提高了系统的灵活...
中介者模式通过引入一个中介对象(Mediator),使得各个对象(Colleague)只需要与中介者交互,而不直接与其他对象通信,从而减少了对象间的直接依赖。 在标题和描述中提到的实验课题是利用中介者模式来简化多对象...
总的来说,`Mediator.cpp`和`Mediator.py`分别展示了C++和Python中如何运用中介者模式来简化对象间的交互,通过中介者对象来实现松散耦合。这样的设计使得系统更加模块化,方便后续的维护和扩展。
在`MediatorPattern.cpp`和`MediatorPattern.h`这两个文件中,我们可以预期看到中介者模式的具体实现。`MediatorPattern.h`可能包含了中介者和同事类的定义,而`MediatorPattern.cpp`则实现了这些类的成员函数。 ...
1. **中介者(Mediator)**: 这是模式的核心,它定义了各个同事对象之间的交互接口。中介者对象负责协调各个同事对象的行为,解耦它们之间的具体实现,使得同事对象可以独立地改变它们的交互方式。 2. **具体中介者...
**中介者模式(Mediator Pattern)** 中介者模式是一种行为设计模式,它的主要目标是减少对象之间的耦合性,通过引入一个中介对象来协调多个对象之间的交互。在传统的多对象交互场景中,对象之间可能存在复杂的依赖...
中介者模式(Mediator)是设计模式的一种,主要用于降低多个对象之间的复杂交互。在JavaScript中,当多个对象之间存在复杂的依赖关系,导致类之间的耦合度增加时,中介者模式可以提供一个解决方案。通过引入一个中介...
中介者模式是一种设计模式,它在软件工程中用于降低多个对象之间的复杂交互。这个模式的主要目的是通过引入一个中介对象来封装一系列对象之间的交互,使得这些对象不必显式地相互引用,从而让对象间的耦合度降低,...
中介者模式的完整代码。 程序默认使用vs开发。其他开发工具可能需要做少许调整。