中介者模式【Mediator Pattern】

栏目: 后端 · 发布时间: 8年前

内容简介:中介者模式【Mediator Pattern】

各位好,大家都是来自五湖四海,都要生存,于是都找了个靠山——公司,给你发薪水的地方,那公司就要想尽办法盈利赚钱,盈利方法则不尽相同,但是作为公司都有相同三个环节:采购、销售和库存,这个怎么说呢?比如一个软件公司,要开发软件,需要开发环境吧, Windows 操作系统,数据库产品等,这你得买吧,那就是采购,开发完毕一个产品还要把产品推销出去,推销出去了大家才有钱赚,不推销出去大家都去喝西北风呀,既然有产品就必然有库存,软件产品也有库存,你总要拷贝吧,虽然是不需要占用库房空间,那也是要占用光盘或硬盘,这也是库存,再比如做咨询服务的公司,它要采购什么?采购知识,采购经验,这是这类企业的生存之本,销售的也是知识和经验,库存同样是知识和经验。尽然进销存是这么的重要,我们今天就来讲讲它的原理和设计,我相信很多人都已经开发过这种类型的软件,基本上都形成了固定套路,不管是单机版还是网络版,一般的做法都是通过数据库来完成相关产品的管理,相对来说还是比较简单的项目,三个模块之间的示意图如下:

中介者模式【Mediator Pattern】

我们从这个示意图上可以看出,三个模块是相互依赖的,基本上是你中有我,我中有你,为什么呢?我们就以一个终端销售商(什么是终端销售商?就是以服务最终客户为目标的企业,比如 XX 超市,国美电器等等)为例子,比如采购部门要采购 IBM 型号的电脑了,它是根据什么来决定采购的呢?根据两个要素:

销售情况。销售部门要反馈销售情况,畅销就多采购,滞销就不采购;

库存情况。即使是畅销产品,库存都有 1000 台了,每天才卖出去 10 台,还要采购吗?!

销售模块是企业的盈利核心,也是对其他两个模块有影响的:

库存情况。库房有货,才能销售,没货空手套白狼是不行的;

督促采购。在特殊情况下,比如一个企业客户一下子要卖 100 台电脑,你库存里自由 80 台,怎么办?催采购部门赶快采购呀!

同样的,库存管理也对其他两个模块有影响,库房是有容积限制的,不可能无限大,所以就有了清仓处理,那就要求采购部门别采购了,同时销售部门赶快打折销售。

从以上分析来看,这三个模块都是有自己的行为,并且与其他模块之间的行为产生关联关系,就类似我们在办公室中的同事,大家各干各的活,但是彼此之间还是有交叉的,于是乎大家之间就产生紧耦合,也就是一个团队。我们先来实现这个进销存,先看类图:

中介者模式【Mediator Pattern】

Purchase 负责采购管理,buyIBMComputer 是指定了采购 IBM 电脑,refuseBuyIBM 是不再采购 IBM 了,源代码如下:

public class Purchase {
//采购IBM型号的电脑
public void buyIBMcomputer(int number){
 //访问库存
 Stock stock = new Stock();
 //访问销售
 Sale sale = new Sale();

 //电脑的销售情况
 int saleStatus = sale.getSaleStatus();

 if(saleStatus>80){ //销售情况良好
 System.out.println("采购IBM电脑:"+number + "台");
 stock.increase(number);
 }else{ //销售情况不好
 int buyNumber = number/2; //折半采购
 System.out.println("采购IBM电脑:"+buyNumber+ "台");
 }
 }

//不再采购IBM电脑
public void refuseBuyIBM(){
 System.out.println("不再采购IBM电脑");
 }
}

Purchase 定义了采购电脑的一个标准,如果销售情况比较好,大于 80 分,你让我采购多少我就采购多少;销售情况不好,你让我采购 100 台,我就采购 50 台,对折采购。电脑采购完毕了,肯定要放到库房中,因此要调用库存的方法,增加库存电脑数量。我们继续来看库房 Stock 类:

public class Stock {
//刚开始有100台电脑
private static int COMPUTER_NUMBER =100;

//库存增加
public void increase(int number){
 COMPUTER_NUMBER = COMPUTER_NUMBER + number;
 System.out.println("库存数量为:"+COMPUTER_NUMBER);
 }

//库存降低
public void decrease(int number){
 COMPUTER_NUMBER = COMPUTER_NUMBER - number;
 System.out.println("库存数量为:"+COMPUTER_NUMBER);
 }

//获得库存数量
public int getStockNumber(){
 return COMPUTER_NUMBER;
 }

//存货压力大了,就要通知采购人员不要采购,销售人员要尽快销售
public void clearStock(){
 Purchase purchase = new Purchase();
 Sale sale = new Sale();
 System.out.println("清理存货数量为:"+COMPUTER_NUMBER);
 //要求折价销售
 sale.offSale();
 //要求采购人员不要采购
 purchase.refuseBuyIBM();

 }
}

库房中的货物数量肯定有增加和减少了,同时库房还有一个容量显示,达到一定的容量后就要求对一些商品进行折价处理,腾出更多的空间容纳新产品,于是就有了 clearStock 方法,既然是清仓处理肯定就要折价销售了,于是在 Sale 这个类中就有了 offSale 方法,我们来看 Sale 源代码:

public class Sale {

//销售IBM型号的电脑
public void sellIBMComputer(int number){
 //访问库存
 Stock stock = new Stock();
 //访问采购
 Purchase purchase = new Purchase();

 if(stock.getStockNumber()<number){ //库存数量不够销售
 purchase.buyIBMcomputer(number);
 }
System.out.println("销售IBM电脑"+number+"台");
 stock.decrease(number);
 }

//反馈销售情况,0——100之间变化,0代表根本就没人卖,100代表非常畅销,出一个卖一个
public int getSaleStatus(){
 Random rand = new Random(System.currentTimeMillis());
 int saleStatus = rand.nextInt(100);
 System.out.println("IBM电脑的销售情况为:"+saleStatus);
 return saleStatus;
 }

//折价处理
public void offSale(){
 //库房有多少卖多少
 Stock stock = new Stock();
 System.out.println("折价销售IBM电脑"+stock.getStockNumber()+"台");
 }
}

Sale 类中的 getSaleStatus 是获得销售情况,这个当然要出现在 Sale 类中了,记住恰当的类放到恰当的类中,销售情况当然只有销售人员才能反馈出来了,通过百分制的机制衡量销售情况。我们再来看场景类是怎么运行的:

public class Client {

public static void main(String[] args) {
 //采购人员采购电脑
 System.out.println("------采购人员采购电脑--------");
 Purchase purchase = new Purchase();
 purchase.buyIBMcomputer(100);

 //销售人员销售电脑
 System.out.println("\n------销售人员销售电脑--------");
 Sale sale = new Sale();
 sale.sellIBMComputer(1);

 //库房管理人员管理库存
 System.out.println("\n------库房管理人员清库处理--------");
 Stock stock = new Stock();
 stock.clearStock();
 }
}

我们在场景类中模拟了三种人员类型的活动:采购人员采购电脑,销售人员销售电脑,库管员管理库存,运行结果如下:

------采购人员采购电脑--------
IBM 电脑的销售情况为:95
采购 IBM 电脑:100 台
库存数量为:200
------销售人员销售电脑--------
销售 IBM 电脑 1 台
库存数量为:199
------库房管理人员清库处理-------- 
清理存货数量为:199
折价销售 IBM 电脑 199 台
不再采购 IBM 电脑

运行结果也是我们期望的,三个不同类型的参与者完成了各自的活动。但是…但是…,你难道就没有发现这三个类间是彼此关联的吗?每个类都与其他两个类产生了关联关系,迪米特法则教育我们“每个类只和朋友类交流”,这个朋友类可不是越多越好,越多耦合性越大,改一个对象而要修改一片对象,这可不是面向对象设计所期望的,而且这还是就三个模块的情况,比较简单的一个小项目,如果有十个八个这样的模块是不是就要歇菜了,我们把进销存扩充一下,如下图的情况:

中介者模式【Mediator Pattern】

是不是看到一个蜘蛛网的结构,这个别说是编写程序了,就是给人看估计能让一大批的人昏倒!每个对象都要和其他的几个对象交流,对象越多,每个对象要交流的成本也就越多了,就单独维护这些对象的交流基本上就能让一大批 程序员 望而却步,这明摆着不是人干的活嘛!从这方面来,我们已经发现设计的缺陷,作为一个架构师,发现缺陷就要想办法来修改,我们思考一下,怎么来修改。

大家都是学计算机的,应该在上学的时候讲过一些网络的基本知识,还记得网络拓扑有几种类型吗?总线型,环型,星型,(什么?想不起来?!惩罚一下自己去),我们来想想星型拓扑是什么什么样子的,如下图:

中介者模式【Mediator Pattern】

星型网络拓扑中每个计算机通过交换机和其他计算机进行数据交换,各个计算机之间并没有直接出现交互的情况,结构简单,而且稳定,只要中间那个交换机不瘫痪,整个网络就不会发生大的故障,公司和网吧一般都采用星型网络,那也说明星型拓扑是深得民心,那我们来想想是不是可以把这种星型结构引入到我们的设计中呢?说干就干,我们先画一个示意图:

中介者模式【Mediator Pattern】

加入了一个中介者作为三个模块的交流核心,每个模块之间不再相互交流,要交流就通过中介者进行,每个模块只负责自己的业务逻辑,不属于自己的则丢给中介者来处理,看类图:

中介者模式【Mediator Pattern】

建立了两个抽象类 AbstractMediator 和 AbstractColeague,每个对象只是与中介者 Mediator 之间产生依赖,与其他对象之间没有直接的关系,AbstractMediator 的作用是把中介者的抽象定义,定义了一个抽象方法 execute,我们来看源代码:

public abstract class AbstractMediator {
protected Purchase purchase;
protected Sale sale;
protected Stock stock;

//构造函数
public AbstractMediator(){
 purchase = new Purchase(this);
 sale = new Sale(this);
 stock = new Stock(this);
 }

//中介者最重要的方法,叫做事件方法,处理多个对象之间的关系
public abstract void execute(String str,Object...objects);
}

我们再来看具体的中介者,中介者可以根据业务的要求产生多个中介者(一般情况只有一个中介者),划分各个终结者的职责。我们来看 Mediator 源码:

public class Mediator extends AbstractMediator {
//中介者最重要的方法
public void execute(String str,Object...objects){
 if(str.equals("purchase.buy")){ //采购电脑
 this.buyComputer((Integer)objects[0]);
 }else if(str.equals("sale.sell")){ //销售电脑
 this.sellComputer((Integer)objects[0]);
 }else if(str.equals("sale.offsell")){ //折价销售
 this.offSell();
 }else if(str.equals("stock.clear")){ //清仓处理
 this.clearStock();
 }
 }

//采购电脑
private void buyComputer(int number){
 int saleStatus = super.sale.getSaleStatus();
 if(saleStatus>80){ //销售情况良好
 System.out.println("采购IBM电脑:"+number + "台");
 super.stock.increase(number);
 }else{ //销售情况不好
 int buyNumber = number/2; //折半采购
 System.out.println("采购IBM电脑:"+buyNumber+ "台");
 }
 }

//销售电脑
private void sellComputer(int number){
 if(super.stock.getStockNumber()<number){ //库存数量不够销售
 super.purchase.buyIBMcomputer(number);
 }
 super.stock.decrease(number);
 }

//折价销售电脑
private void offSell(){
 System.out.println("折价销售IBM电脑"+stock.getStockNumber()+"台");
 }
//清仓处理
private void clearStock(){
 //要求清仓销售
 super.sale.offSale();
 //要求采购人员不要采购
 super.purchase.refuseBuyIBM();
 }
}

中介者 Mediator 有定义了多个 Private 方法,其目标是处理各个对象之间的依赖关系,即是说把原有一个对象要依赖多个对象的情况移到中介者的 Private 方法中实现,在实际项目中,一般的做法是中介者按照职责进行划分,每个中介者处理一个或多个类似的关联请求。 我们再来看 AbstractColleague 源码:

public abstract class AbstractColleague {
protected AbstractMediator mediator;
public AbstractColleague(AbstractMediator _mediator){
 this.mediator = _mediator;
 }
}

采购类 Purchase 的源码如下:

public class Purchase extends AbstractColleague{

public Purchase(AbstractMediator _mediator){
 super(_mediator);
 }
//采购IBM型号的电脑
public void buyIBMcomputer(int number){
 super.mediator.execute("purchase.buy", number);
 }

//不在采购IBM电脑
public void refuseBuyIBM(){
 System.out.println("不再采购IBM电脑");
 }
}

Purchase 类是不是简化了很多,看着也清晰了很多,处理自己的职责,与外界有关系的事件处理则交给了中介者来完成。再来看 Stock 类:

public class Stock extends AbstractColleague {
public Stock(AbstractMediator _mediator){
 super(_mediator);
 }
//刚开始有100台电脑
private static int COMPUTER_NUMBER =100;

//库存增加
public void increase(int number){
 COMPUTER_NUMBER = COMPUTER_NUMBER + number;
 System.out.println("库存数量为:"+COMPUTER_NUMBER);
 }

//库存降低
public void decrease(int number){
 COMPUTER_NUMBER = COMPUTER_NUMBER - number;
 System.out.println("库存数量为:"+COMPUTER_NUMBER);
 }

//获得库存数量
public int getStockNumber(){
 return COMPUTER_NUMBER;
 }

//存货压力大了,就要通知采购人员不要采购,销售人员要尽快销售
public void clearStock(){
 System.out.println("清理存货数量为:"+COMPUTER_NUMBER);
 super.mediator.execute("stock.clear");

 }
}

以下为 Sale 类的源码:

public class Sale extends AbstractColleague {
public Sale(AbstractMediator _mediator){
 super(_mediator);
 } 

//销售IBM型号的电脑
public void sellIBMComputer(int number){
 super.mediator.execute("sale.sell", number);
 System.out.println("销售IBM电脑"+number+"台");
 }

//反馈销售情况,0——100之间变化,0代表根本就没人卖,100代表非常畅销,出1一个卖一个
public int getSaleStatus(){
 Random rand = new Random(System.currentTimeMillis());
 int saleStatus = rand.nextInt(100);
 System.out.println("IBM电脑的销售情况为:"+saleStatus);
 return saleStatus;
 }

//折价处理
public void offSale(){
 super.mediator.execute("sale.offsell");
 }
}

再来看场景类的变化:

public class Client {

public static void main(String[] args) {
 AbstractMediator mediator = new Mediator();
 //采购人员采购电脑
 System.out.println("------采购人员采购电脑--------");
 Purchase purchase = new Purchase(mediator);
 purchase.buyIBMcomputer(100);

 //销售人员销售电脑
 System.out.println("\n------销售人员销售电脑--------");
 Sale sale = new Sale(mediator);
 sale.sellIBMComputer(1);

 //库房管理人员管理库存
 System.out.println("\n------库房管理人员清库处理--------");
 Stock stock = new Stock(mediator);
 stock.clearStock();
 } 
}

在场景类中增加了一个中介者,然后分别传递到三个同事类中,三个类都具有相同的特性:只负责处理自己的活动(行为),与自己无关的活动就丢给中介者处理,程序运行的结果是相同的。从项目设计上来看,加入了中介者,设计结构清晰了很多,而且类间的耦合性大大减少,代码质量也有了很大的提升。

以上讲解的模式就是中介者模式,在多个对象依赖的情况喜爱,通过加入中介者角色,取消了多个对象的关联或依关系,减少了对象的耦合性,其通用类图为:

中介者模式【Mediator Pattern】

从类图中看,中介者模式有以下几部分组成:

抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口用于各同事角色之间的通信。

具体中介者(Concrete Mediator)角色:具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

同事(Colleague)角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等等,这种方法叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。

在前几张的讲解中,每个模式的类都已经给出,但是却没有给出通用的源代码,感觉这种方式不是很好,因此从本章开始,都加入通用源代码。中介者的通用源码结构如下所示,先看中介者 Mediator 类:

public abstract class Mediator {
//定义同事类
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;

//通过getter/setter方法把同事类注入进来
public ConcreteColleague1 getC1() {
 return c1; 
 }
public void setC1(ConcreteColleague1 c1) {
 this.c1 = c1;
 }
public ConcreteColleague2 getC2() {
 return c2;
 }
public void setC2(ConcreteColleague2 c2) {
 this.c2 = c2;
 }

//中介者模式的业务逻辑
public abstract void doSomething1();
public abstract void doSomething2();

}

在 Mediator 抽象类中我们只定义了同事类的注入,为什么使用同事实现类注入而不使用抽象类注入呢?那是因为同事类虽然有抽象,但是这个抽象也太抽象了,根本就没有每个同事类所必须要完成的业务方法,当然如果每个同事类都有相同的方法,比如 execute,handler 等,那当然注入抽象类,做到依赖倒转。

具体的中介者一般只有一个,其源码如下:

public class ConcreteMediator extends Mediator {
@Override
public void doSomething1() {
 //调用同事类的方法,只要是public方法都可以调用
 super.c1.selfMethod1();
 super.c2.selfMethod2();
 }
public void doSomething2() {
 super.c1.selfMethod1();
 super.c2.selfMethod2();
 }
}

中介者所具有的方法 doSomething1 和 doSomething2 都是比较复杂的业务逻辑,都是为同事类服务的,其实现是依赖了各个同事类来完成。同事类的基类如下:

public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator _mediator){
 this.mediator = _mediator;
 }
}

这个基类也是非常简单的,一般来说中介者模式中的抽象都是比较简单,是为了建立这个中介而服务的,同事实现类的源码如下:

public class ConcreteColleague1 extends Colleague {
//通过构造函数传递中介者
public ConcreteColleague1(Mediator _mediator){
 super(_mediator);
 }

//自有方法 self-method
public void selfMethod1(){
 //处理自己的业务逻辑
 }

//依赖方法 dep-method
public void depMethod1(){
 //处理自己的业务逻辑
 //自己不能处理的业务逻辑,委托给中介者处理
 super.mediator.doSomething1();

 }

}
public class ConcreteColleague2 extends Colleague {
//通过构造函数传递中介者
public ConcreteColleague2(Mediator _mediator){
 super(_mediator); 
 }

//自有方法 self-method
public void selfMethod2(){
 //处理自己的业务逻辑
 }

//依赖方法 dep-method
public void depMethod2(){
 //处理自己的业务逻辑
 //自己不能处理的业务逻辑,委托给中介者处理
 super.mediator.doSomething2();
 }

}

为什么同事类要使用构造函数注入中介者而中介者使用 getter/setter 方式注入同事类呢?想过没有?那是因为同事类必须有中介者,而中介者可以只有部分同事类。

中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然也同时减低了类间的耦合。它的缺点呢就是中介者会膨胀的很大,而且逻辑会很复杂,因为所有的原本 N 个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就复杂。

中介者模式简单,但是简单不代表容易使用,这是 23 个模式中最容被误用的模式。我们知道在面向对象的编程中,对象和对象之间必然会有依赖关系,如果你写了一个类,这个类和其他类没有任何的依赖关系,其他类也不依赖这个类,那这个类就是一个“孤岛”嘛,在项目中就没有必要存在!这就像是人类,如果一个人永远独立生活,与任何人都没有关系,那这个人基本上就算是野人了——排除在人类这个定义之外。类之间的依赖关系是必然存在的,一个类依赖多个类的情况也是存在的,存在即合理,那是否可以说只要有多个依赖关系就考虑使用中介者模式呢?答案是否定的,中介者模式未必就能帮你把原本凌乱的逻辑整理的清清楚楚,而且中介者模式也是有缺点的,这个缺点在不当的使用时会被放大,比如原本就简单的几个对象依赖关系,如果为了使用模式而加入了中介者,必然导致中介者的逻辑复杂化,因此中介者模式的使用需要“量力而行”,那在什么环境下才使用中介者模式呢?中介者模式适用于多个对象之间紧密耦合,耦合的标准可以这样来衡量:在类图中出现了蜘蛛网状结构,在这种情况下一定要考虑使用中介者模式,有利于把蜘蛛网梳理为一个星型结构,使原本复杂混乱关系变得清晰简单。

中介者模式也叫做调停者模式,是什么意思呢?一个对象要和 N 多个对象交流,是不是就像对象间的战争,很混乱,你中有我,我中有你,那怎么才能调停这种矛盾呢?加入一个中心,所有的类都和中心交流,中心说怎么处理就这么处理,我们举一些在开发和生活中经常会碰到例子,再举四个例子如下:

机场调度中心。大家在每个机场都会看到有一个叫做“XX 机场调度中心”,这个是做什么用的呢?就是具体的中介者,调度每一架要降落和起飞的飞机,一架分机(同事类)飞到机场上空了,就询问(同事类方法)调度中心(中介者)“我是否可以降落”,“降落到那个跑道”,然后调度中心(中介者)查看其他飞机(同事类)情况,通知飞机降落,我们来设想一下,如果没有机场调度中心会是什么样子的:飞机到机场了,自己要先看看有没有飞机和自己一起降落的,有没有空跑道,停机位是否具备等等情况,这不是要了飞行员老命才怪!

MVC 框架。大家都应该使用过 Struts 吧,MVC 框架,其中的 C(Controller)就是一个中介者,叫做前端控制器(Front Controller),它的作用就是把 M(Model,业务逻辑)和 V(View,视图)隔离开,协调 M和 V 协同工作,把 M 运行的结果和 V 代表的视图融合成一个前端可以展示的页面,减少 M 和 V 的依赖关系。MVC 框架已经成为一个非常流行、成熟的开发框架,这也是中介者模式优秀的一个体现。

C/S 结构。C/S 结构的应用也是一个典型的中介者模式,比如 MSN,张三发一个消息给李四,其过程应该是这样的:张三发送消息,MSN 服务器(中介者)接受到消息,查找李四,把消息发送到李四,同时通知张三,消息已经发送,在这里 MSN 服务器就是一个中转站,负责协调两个客户端的信息交流,与此相反的就是 IPMSG(也叫飞鸽)没有使用中介者,直接使用了 UDP 广播的方式,每个客户端既是客户端也是服务端。

中介服务。现在中介服务非常多,比如租房中介,出国中介,这些也都是中介模式的具体体现,比如你去租房子,如果没有房屋中介,你就必须一个一个小区的找,看看有没有空房子,有没有适合自己的房子,找到房子后还要和房东签合约,自己检查房屋的家具、水电煤等,有了中介后,你就省心多了,找中介,然后安排看房子,看中了,签合约,中介帮你检查房屋家具、水电煤等等。这也是中介模式的实际应用。

不知道大家有没有发觉,这章讲的中介者模式很少用到接口或者抽象类,这与依赖倒转原则是冲突的,确实是,这是什么原因呢?首先说同事类,既然是同事类而不是兄弟类(有相同的血缘)那也说明这些类之间是协作关系,完成不同的任务,处理不同的业务,所以不能在抽象类或接口中严格定义同事类必须具有的方法(从这点也可以看出继承是侵入性的),这是不合适的,就像你我是同事,虽然我们大家都是朝九晚五的上班,但是你跟我干的活肯定不同,不可能抽象出一个父类统一定义同事所必须有的方法,当然也有办法定义,每个同事都要吃饭,都要上厕所,那把这些最基本的信息封装到抽象中是可以的,但问题是这些最基本行为或属性是中介者模式要关心的嘛?如果两个对象不能提炼出共性,那就不要刻意的去追求两者的抽象,抽象只要定义出模式需要的角色即可。其次是中介者的原因,在一个项目中中介者模式可能被多个模块采用,每个中介者所围绕的同事类各不相同,你能抽象出一个具有共性的中介者吗?不可能,一个中介者抽象类一般只有一个实现者,除非中介者逻辑非常大,代码量非常高,这时才会出现多个中介者的情况,所有,对中介者来说,抽象已经没有太多的必要。

中介者模式是一个非常好的封装模式,也是一个很容易被滥用的模式,一个对象依赖几个对象是再正常不过的事情,但是纯理论家就会要求使用中介者模式来封装这种依赖关系,这是非常危险的信号,使用中介模式就必然会带来中介者的膨胀问题,这在一个项目中时很不恰当的,那到底在什么情况下使用中介者模式呢?大家可以在如下的情况下尝试使用中介者模式:

1、 N 个对象之间产生了相互的依赖关系,其中 N 大于  2,注意是相互的依赖;

2、 多个对象有依赖关系,但是依赖的行为尚不确定或者有发生改变的可能,在这种情况下一般建议采用中介者模式,降低变更引起的风险扩散;

3、 产品开发。其中一个明显的例子就是 MVC 框架,把这个应用到产品中,可以提升产品的性能和扩展性,但是作为项目开发就未必,项目是以交付投产为目标,而产品以稳定、高效、扩展为宗旨。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First HTML and CSS

Head First HTML and CSS

Elisabeth Robson、Eric Freeman / O'Reilly Media / 2012-9-8 / USD 39.99

Tired of reading HTML books that only make sense after you're an expert? Then it's about time you picked up Head First HTML and really learned HTML. You want to learn HTML so you can finally create th......一起来看看 《Head First HTML and CSS》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具