设计模式—— 十四 :中介者模式

什么是中介者模式?

中介者模式的定义:

Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.(用一个中介对象封装一系列的对象 交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它 们之间的交互。)

中介模式通用类图如下:

图14-1:中介者模式通用类图

在这里插入图片描述

中介者模式由以下几部分组成:

● Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
● ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现 协作行为,它维持了对各个同事对象的引用。
● Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类 实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
● ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的 状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介 者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep- Method)。

中介者模式的核心在于中介者类的引入,在中介者模式中,中介者类承担了两方面的职责:

  • (1) 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中 介者在结构上的支持。
  • (2) 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致的和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者 根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。

中介者模式通用代码如下:

  • 抽象中介者
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Mediator</span> {
	<span style="color:#a0a1a7"><em>// 定义同事类</em></span>
	<span style="color:#a626a4">protected</span> ConcreteColleague1 c1;
	<span style="color:#a626a4">protected</span> ConcreteColleague2 c2;

	<span style="color:#a0a1a7"><em>// 通过getter/setter方法把同事类注入进来</em></span>
	<span style="color:#a626a4">public</span> ConcreteColleague1 <span style="color:#4078f2">getC1</span>() {
		<span style="color:#a626a4">return</span> c1;
	}

	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">setC1</span>(ConcreteColleague1 c1) {
		<span style="color:#c18401">this</span>.c1 = c1;
	}

	<span style="color:#a626a4">public</span> ConcreteColleague2 <span style="color:#4078f2">getC2</span>() {
		<span style="color:#a626a4">return</span> c2;
	}

	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">setC2</span>(ConcreteColleague2 c2) {
		<span style="color:#c18401">this</span>.c2 = c2;
	}
	<span style="color:#a0a1a7"><em>// 中介者模式的业务逻辑 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">doSomething1</span>(); 
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">doSomething2</span>();
}
</code></span></span>
  • 中介者:在具体中介者类中将调用同事类的方法,调用时可以增加一些自己的业务代码对调用进行控制。
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">ConcreteMediator</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">Mediator</span> {
	<span style="color:#4078f2">@Override</span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">doSomething1</span>() {
		<span style="color:#a0a1a7"><em>// 调用同事类的方法,只要是public方法都可以调用</em></span>
		<span style="color:#c18401">super</span>.c1.selfMethod1();
		<span style="color:#c18401">super</span>.c2.selfMethod2();
	}

	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">doSomething2</span>() {
		<span style="color:#c18401">super</span>.c1.selfMethod1();
		<span style="color:#c18401">super</span>.c2.selfMethod2();
	}
}
</code></span></span>
  • 抽象同事类
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Colleague</span> {
	<span style="color:#a626a4">protected</span> Mediator mediator;

	<span style="color:#a626a4">public</span> <span style="color:#4078f2">Colleague</span>(Mediator _mediator) {
		<span style="color:#c18401">this</span>.mediator = _mediator;
	}
}

</code></span></span>
  • 具体同事类:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">ConcreteColleague1</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">Colleague</span> {
	<span style="color:#a0a1a7"><em>// 通过构造函数传递中介者</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">ConcreteColleague1</span>(Mediator _mediator) {
		<span style="color:#c18401">super</span>(_mediator);
	}

	<span style="color:#a0a1a7"><em>// 自有方法 self-method</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">selfMethod1</span>() {
		<span style="color:#a0a1a7"><em>// 处理自己的业务逻辑</em></span>
	}

	<span style="color:#a0a1a7"><em>// 依赖方法 dep-method</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">depMethod1</span>() {
		<span style="color:#a0a1a7"><em>// 处理自己的业务逻辑</em></span>
		<span style="color:#a0a1a7"><em>// 自己不能处理的业务逻辑,委托给中介者处理</em></span>
		<span style="color:#c18401">super</span>.mediator.doSomething1();
	}
}



<span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">ConcreteColleague2</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">Colleague</span> {
	<span style="color:#a0a1a7"><em>// 通过构造函数传递中介者</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">ConcreteColleague2</span>(Mediator _mediator) {
		<span style="color:#c18401">super</span>(_mediator);
	}

	<span style="color:#a0a1a7"><em>// 自有方法 self-method</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">selfMethod2</span>() {
		<span style="color:#a0a1a7"><em>// 处理自己的业务逻辑</em></span>
	}<span style="color:#a0a1a7"><em>// 依赖方法 dep-method</em></span>

	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">depMethod2</span>() {
		<span style="color:#a0a1a7"><em>// 处理自己的业务逻辑</em></span>
		<span style="color:#a0a1a7"><em>// 自己不能处理的业务逻辑,委托给中介者处理</em></span>
		<span style="color:#c18401">super</span>.mediator.doSomething2();
	}
}
</code></span></span>

为什么要用中介者模式?

现在有一个进销存的场景:

图14-2:进销存示意图

在这里插入图片描述
三个模块是相互依赖的。以一个终端销售商(以服务最终客户为目标的企业,比如某某超市、某某商店等)为例,采购部门要采购IBM的电 脑,它根据以下两个要素来决定采购数量。

● 销售情况: 销售部门要反馈销售情况,畅销就多采购,滞销就不采购。
● 库存情况: 即使是畅销产品,库存都有1000台了,每天才卖出去10台,也就不需要再采购了! 销售模块是企业的赢利核心,对其他两个模块也有影响:
● 库存情况: 库房有货,才能销售,空手套白狼是不行的。
● 督促采购: 在特殊情况下,比如一个企业客户要一次性购买100台电脑,库存只有80台,这时需要催促采购部门赶快采购!

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

使用中介者模式前

从以上分析来看,这三个模块都有自己的行为,并且与其他模块之间的行为产生关联。设计
的类图如下:

图14-3: 简单的进销存类图

在这里插入图片描述

Purchase负责采购管理,buyIBMComputer指定了采购IBM电脑,refuseBuyIBM是指不再采 购IBM。

具体实现:

  • 采购管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Purchase</span> {
	<span style="color:#a0a1a7"><em>// 采购IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">buyIBMcomputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#a0a1a7"><em>// 访问库存</em></span>
		<span style="color:#986801">Stock</span> <span style="color:#986801">stock</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>();
		<span style="color:#a0a1a7"><em>// 访问销售</em></span>
		<span style="color:#986801">Sale</span> <span style="color:#986801">sale</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Sale</span>();
		<span style="color:#a0a1a7"><em>// 电脑的销售情况</em></span>
		<span style="color:#986801">int</span> <span style="color:#986801">saleStatus</span> <span style="color:#ab5656">=</span> sale.getSaleStatus();
		<span style="color:#a626a4">if</span> (saleStatus > <span style="color:#986801">80</span>) {
			<span style="color:#a0a1a7"><em>// 销售情况良好</em></span>
			System.out.println(<span style="color:#50a14f">"采购IBM电脑:"</span> + number + <span style="color:#50a14f">"台"</span>);
			stock.increase(number);
		} <span style="color:#a626a4">else</span> {
			<span style="color:#a0a1a7"><em>// 销售情况不好</em></span>
			<span style="color:#986801">int</span> <span style="color:#986801">buyNumber</span> <span style="color:#ab5656">=</span> number / <span style="color:#986801">2</span>;
			<span style="color:#a0a1a7"><em>// 折半采购</em></span>
			System.out.println(<span style="color:#50a14f">"采购IBM电脑:"</span> + buyNumber + <span style="color:#50a14f">"台"</span>);
		}
	}

	<span style="color:#a0a1a7"><em>// 不再采购IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">refuseBuyIBM</span>() {
		System.out.println(<span style="color:#50a14f">"不再采购IBM电脑"</span>);
	}
}

</code></span></span>
  • 库存管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Stock</span> {
	<span style="color:#a0a1a7"><em>// 刚开始有100台电脑</em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">static</span> <span style="color:#986801">int</span> <span style="color:#986801">COMPUTER_NUMBER</span> <span style="color:#ab5656">=</span> <span style="color:#986801">100</span>;

	<span style="color:#a0a1a7"><em>// 库存增加</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">increase</span>(<span style="color:#986801">int</span> number) {
		COMPUTER_NUMBER = COMPUTER_NUMBER + number;
		System.out.println(<span style="color:#50a14f">"库存数量为:"</span> + COMPUTER_NUMBER);
	}

	<span style="color:#a0a1a7"><em>// 库存降低</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">decrease</span>(<span style="color:#986801">int</span> number) {
		COMPUTER_NUMBER = COMPUTER_NUMBER - number;
		System.out.println(<span style="color:#50a14f">"库存数量为:"</span> + COMPUTER_NUMBER);
	}<span style="color:#a0a1a7"><em>// 获得库存数量</em></span>

	<span style="color:#a626a4">public</span> <span style="color:#986801">int</span> <span style="color:#4078f2">getStockNumber</span>() {
		<span style="color:#a626a4">return</span> COMPUTER_NUMBER;
	}

    <span style="color:#a0a1a7"><em>//存货压力大了,就要通知采购人员不要采购,销售人员要尽快销售</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">clearStock</span>() {
		<span style="color:#986801">Purchase</span> <span style="color:#986801">purchase</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Purchase</span>();
		<span style="color:#986801">Sale</span> <span style="color:#986801">sale</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Sale</span>();
		System.out.println(<span style="color:#50a14f">"清理存货数量为:"</span> + COMPUTER_NUMBER); 
		<span style="color:#a0a1a7"><em>// 要求折价销售</em></span>
		sale.offSale();
        <span style="color:#a0a1a7"><em>//要求采购人员不要采购 </em></span>
		purchase.refuseBuyIBM();
	}
}
</code></span></span>
  • 销售管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Sale</span> {
	<span style="color:#a0a1a7"><em>// 销售IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">sellIBMComputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#a0a1a7"><em>// 访问库存</em></span>
		<span style="color:#986801">Stock</span> <span style="color:#986801">stock</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>();
		<span style="color:#a0a1a7"><em>// 访问采购</em></span>
		<span style="color:#986801">Purchase</span> <span style="color:#986801">purchase</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Purchase</span>();
		<span style="color:#a626a4">if</span> (stock.getStockNumber() < number) {
			<span style="color:#a0a1a7"><em>// 库存数量不够销售</em></span>
			purchase.buyIBMcomputer(number);
		}
		System.out.println(<span style="color:#50a14f">"销售IBM电脑"</span> + number + <span style="color:#50a14f">"台"</span>);
		stock.decrease(number);
	}

	<span style="color:#a0a1a7"><em>// 反馈销售情况,0~100之间变化,0代表根本就没人卖,100代表非常畅销,出一个卖一个</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#986801">int</span> <span style="color:#4078f2">getSaleStatus</span>() {
		<span style="color:#986801">Random</span> <span style="color:#986801">rand</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Random</span>(System.currentTimeMillis());
		<span style="color:#986801">int</span> <span style="color:#986801">saleStatus</span> <span style="color:#ab5656">=</span> rand.nextInt(<span style="color:#986801">100</span>);
		System.out.println(<span style="color:#50a14f">"IBM电脑的销售情况为:"</span> + saleStatus);
		<span style="color:#a626a4">return</span> saleStatus;
	}

	<span style="color:#a0a1a7"><em>// 折价处理</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">offSale</span>() { <span style="color:#a0a1a7"><em>// 库房有多少卖多少</em></span>
		<span style="color:#986801">Stock</span> <span style="color:#986801">stock</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>();
		System.out.println(<span style="color:#50a14f">"折价销售IBM电脑"</span> + stock.getStockNumber() + <span style="color:#50a14f">"台"</span>);
	}

}
</code></span></span>
  • 场景类:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java">	<span style="color:#a626a4">public</span> <span style="color:#a626a4">static</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">main</span>(String[] args) {
		<span style="color:#a0a1a7"><em>// 采购人员采购电脑</em></span>
		System.out.println(<span style="color:#50a14f">"------采购人员采购电脑--------"</span>);
		<span style="color:#986801">Purchase</span> <span style="color:#986801">purchase</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Purchase</span>();
		purchase.buyIBMcomputer(<span style="color:#986801">100</span>);
		<span style="color:#a0a1a7"><em>// 销售人员销售电脑</em></span>
		System.out.println(<span style="color:#50a14f">"\n------销售人员销售电脑--------"</span>);
		<span style="color:#986801">Sale</span> <span style="color:#986801">sale</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Sale</span>();
		sale.sellIBMComputer(<span style="color:#986801">1</span>);
		<span style="color:#a0a1a7"><em>// 库房管理人员管理库存</em></span>
		System.out.println(<span style="color:#50a14f">"\n------库房管理人员清库处理--------"</span>);
		<span style="color:#986801">Stock</span> <span style="color:#986801">stock</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>();
		stock.clearStock();

	}

}
</code></span></span>

我们在场景类中模拟了三种人员的活动:采购人员采购电脑,销售人员销售电脑,库管员管理库存。

运行结果如下:
在这里插入图片描述

OK,我们的功能都实现了,存在什么问题呢?

每个类都与其他两个类产生了关联关系。迪米特法则认为“每个类只 和朋友类交流”,这个朋友类并非越多越好,朋友类越多,耦合性越大,要想修改一个就得 修改一片,这不是面向对象设计所期望的,况且这还是仅三个模块的情况,属于比较简单的 一个小项目。我们把进销存扩展一下,如图所示:

图14-4:扩展后的进销存示意图

在这里插入图片描述

这样一来,整个模块可以说是很难开发和维护了,所以,这时候就要引入中介者模式。

使用中介者模式后

将之前的进销存结构重新设计:

图14-5:修改后的进销存示意图

在这里插入图片描述加入了一个中介者作为三个模块的交流核心,每个模块之间不再相互交流,要交流就通 过中介者进行。每个模块只负责自己的业务逻辑,不属于自己的则丢给中介者来处理,简化

了各模块之间的耦合关系,类图如图所示:

图14-6:修改后的进销存类图

在这里插入图片描述
建立了两个抽象类AbstractMediator和AbstractColeague,每个对象只是与中介者Mediator 之间产生依赖,与其他对象之间没有直接关系,AbstractMediator的作用是实现中介者的抽象 定义,定义了一个抽象方法execute。

实现如下:

  • 抽象中介者:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">AbstractMediator</span> {
	<span style="color:#a626a4">protected</span> Purchase purchase;
	<span style="color:#a626a4">protected</span> Sale sale;
	<span style="color:#a626a4">protected</span> Stock stock;

	<span style="color:#a0a1a7"><em>// 构造函数</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">AbstractMediator</span>() {
		purchase = <span style="color:#a626a4">new</span> <span style="color:#4078f2">Purchase</span>(<span style="color:#c18401">this</span>);
		sale = <span style="color:#a626a4">new</span> <span style="color:#4078f2">Sale</span>(<span style="color:#c18401">this</span>);
		stock = <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>(<span style="color:#c18401">this</span>);
	}

   <span style="color:#a0a1a7"><em>//中介者最重要的方法叫做事件方法,处理多个对象之间的关系 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">execute</span>(String str, Object... objects);
}
</code></span></span>
  • 具体中介者:
    中介者Mediator定义了多个private方法,其目的是处理各个对象之间的依赖关系,就是说把原有一个对象要依赖多个对象的情况移到中介者的private方法中实现。在实际项目中, 一般的做法是中介者按照职责进行划分,每个中介者处理一个或多个类似的关联请求。
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Mediator</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">AbstractMediator</span> {
	<span style="color:#a0a1a7"><em>// 中介者最重要的方法</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">execute</span>(String str, Object... objects) {
		<span style="color:#a626a4">if</span> (str.equals(<span style="color:#50a14f">"purchase.buy"</span>)) {
			<span style="color:#a0a1a7"><em>// 采购电脑</em></span>
			<span style="color:#c18401">this</span>.buyComputer((Integer) objects[<span style="color:#986801">0</span>]);
		} <span style="color:#a626a4">else</span> <span style="color:#a626a4">if</span> (str.equals(<span style="color:#50a14f">"sale.sell"</span>)) {
			<span style="color:#a0a1a7"><em>// 销售电脑</em></span>
			<span style="color:#c18401">this</span>.sellComputer((Integer) objects[<span style="color:#986801">0</span>]);
		} <span style="color:#a626a4">else</span> <span style="color:#a626a4">if</span> (str.equals(<span style="color:#50a14f">"sale.offsell"</span>)) {
			<span style="color:#a0a1a7"><em>// 折价销售</em></span>
			<span style="color:#c18401">this</span>.offSell();
		} <span style="color:#a626a4">else</span> <span style="color:#a626a4">if</span> (str.equals(<span style="color:#50a14f">"stock.clear"</span>)) {
			<span style="color:#a0a1a7"><em>// 清仓处理</em></span>
			<span style="color:#c18401">this</span>.clearStock();
		}
	}

	<span style="color:#a0a1a7"><em>// 采购电脑</em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">buyComputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#986801">int</span> <span style="color:#986801">saleStatus</span> <span style="color:#ab5656">=</span> <span style="color:#c18401">super</span>.sale.getSaleStatus();
		<span style="color:#a626a4">if</span> (saleStatus > <span style="color:#986801">80</span>) {
			<span style="color:#a0a1a7"><em>// 销售情况良好</em></span>
			System.out.println(<span style="color:#50a14f">"采购IBM电脑:"</span> + number + <span style="color:#50a14f">"台"</span>);
			<span style="color:#c18401">super</span>.stock.increase(number);
		} <span style="color:#a626a4">else</span> {
			<span style="color:#a0a1a7"><em>// 销售情况不好</em></span>
			<span style="color:#986801">int</span> <span style="color:#986801">buyNumber</span> <span style="color:#ab5656">=</span> number / <span style="color:#986801">2</span>;
			<span style="color:#a0a1a7"><em>// 折半采购</em></span>
			System.out.println(<span style="color:#50a14f">"采购IBM电脑:"</span> + buyNumber + <span style="color:#50a14f">"台"</span>);
		}
	}

	<span style="color:#a0a1a7"><em>// 销售电脑</em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">sellComputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#a626a4">if</span> (<span style="color:#c18401">super</span>.stock.getStockNumber() < number) {
			<span style="color:#a0a1a7"><em>// 库存数量不够销售</em></span>
			<span style="color:#c18401">super</span>.purchase.buyIBMcomputer(number);
		}
		<span style="color:#c18401">super</span>.stock.decrease(number);
	}

	<span style="color:#a0a1a7"><em>// 折价销售电脑</em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">offSell</span>() {
		System.out.println(<span style="color:#50a14f">"折价销售IBM电脑"</span> + stock.getStockNumber() + <span style="color:#50a14f">"台"</span>);
	}

	<span style="color:#a0a1a7"><em>// 清仓处理</em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">clearStock</span>() {
		<span style="color:#a0a1a7"><em>// 要求清仓销售</em></span>
		<span style="color:#c18401">super</span>.sale.offSale();
		<span style="color:#a0a1a7"><em>// 要求采购人员不要采购</em></span>
		<span style="color:#c18401">super</span>.purchase.refuseBuyIBM();
	}
}
</code></span></span>
  • 抽象同事类:
    三个具体的实现类分别继承该抽象类
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">abstract</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">AbstractColleague</span> {
	<span style="color:#a626a4">protected</span> AbstractMediator mediator;

	<span style="color:#a626a4">public</span> <span style="color:#4078f2">AbstractColleague</span>(AbstractMediator _mediator) {
		<span style="color:#c18401">this</span>.mediator = _mediator;
	}
}
</code></span></span>
  • 采购管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Purchase</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">AbstractColleague</span> {
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">Purchase</span>(AbstractMediator _mediator) {
		<span style="color:#c18401">super</span>(_mediator);
	}

	<span style="color:#a0a1a7"><em>// 采购IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">buyIBMcomputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#c18401">super</span>.mediator.execute(<span style="color:#50a14f">"purchase.buy"</span>, number);
	}

	<span style="color:#a0a1a7"><em>// 不再采购IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">refuseBuyIBM</span>() {
		System.out.println(<span style="color:#50a14f">"不再采购IBM电脑"</span>);
	}
}
</code></span></span>
  • 库存管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Stock</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">AbstractColleague</span> {
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">Stock</span>(AbstractMediator _mediator) {
		<span style="color:#c18401">super</span>(_mediator);
	}

<span style="color:#a0a1a7"><em>//刚开始有100台电脑 </em></span>
	<span style="color:#a626a4">private</span> <span style="color:#a626a4">static</span> <span style="color:#986801">int</span> <span style="color:#986801">COMPUTER_NUMBER</span> <span style="color:#ab5656">=</span> <span style="color:#986801">100</span>;

<span style="color:#a0a1a7"><em>//库存增加 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">increase</span>(<span style="color:#986801">int</span> number) {
		COMPUTER_NUMBER = COMPUTER_NUMBER + number;
		System.out.println(<span style="color:#50a14f">"库存数量为:"</span> + COMPUTER_NUMBER);
	}

<span style="color:#a0a1a7"><em>//库存降低 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">decrease</span>(<span style="color:#986801">int</span> number) {
		COMPUTER_NUMBER = COMPUTER_NUMBER - number;
		System.out.println(<span style="color:#50a14f">"库存数量为:"</span> + COMPUTER_NUMBER);
	}

<span style="color:#a0a1a7"><em>//获得库存数量 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#986801">int</span> <span style="color:#4078f2">getStockNumber</span>() {
		<span style="color:#a626a4">return</span> COMPUTER_NUMBER;
	}

<span style="color:#a0a1a7"><em>//存货压力大了,就要通知采购人员不要采购,销售人员要尽快销售 </em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">clearStock</span>() {
		System.out.println(<span style="color:#50a14f">"清理存货数量为:"</span> + COMPUTER_NUMBER);
		<span style="color:#c18401">super</span>.mediator.execute(<span style="color:#50a14f">"stock.clear"</span>);
	}
}
</code></span></span>
  • 销售管理:
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Sale</span> <span style="color:#a626a4">extends</span> <span style="color:#4078f2">AbstractColleague</span> {
	<span style="color:#a626a4">public</span> <span style="color:#4078f2">Sale</span>(AbstractMediator _mediator) {
		<span style="color:#c18401">super</span>(_mediator);
	}

	<span style="color:#a0a1a7"><em>// 销售IBM电脑</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">sellIBMComputer</span>(<span style="color:#986801">int</span> number) {
		<span style="color:#c18401">super</span>.mediator.execute(<span style="color:#50a14f">"sale.sell"</span>, number);
		System.out.println(<span style="color:#50a14f">"销售IBM电脑"</span> + number + <span style="color:#50a14f">"台"</span>);
	}

	<span style="color:#a0a1a7"><em>// 反馈销售情况,0~100变化,0代表根本就没人买,100代表非常畅销,出一个卖一个</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#986801">int</span> <span style="color:#4078f2">getSaleStatus</span>() {
		<span style="color:#986801">Random</span> <span style="color:#986801">rand</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Random</span>(System.currentTimeMillis());
		<span style="color:#986801">int</span> <span style="color:#986801">saleStatus</span> <span style="color:#ab5656">=</span> rand.nextInt(<span style="color:#986801">100</span>);
		System.out.println(<span style="color:#50a14f">"IBM电脑的销售情况为:"</span> + saleStatus);
		<span style="color:#a626a4">return</span> saleStatus;
	}

	<span style="color:#a0a1a7"><em>// 折价处理</em></span>
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">offSale</span>() {
		<span style="color:#c18401">super</span>.mediator.execute(<span style="color:#50a14f">"sale.offsell"</span>);
	}
}
</code></span></span>
  • 场景类:
    在场景类中增加了一个中介者,然后分别传递到三个同事类中,三个类都具有相同的特 性:只负责处理自己的活动(行为),与自己无关的活动就丢给中介者处理。
复制代码
<span style="color:#141418"><span style="background-color:#ffffff"><code class="language-java"><span style="color:#a626a4">public</span> <span style="color:#a626a4">class</span> <span style="color:#4078f2">Client</span> {
	<span style="color:#a626a4">public</span> <span style="color:#a626a4">static</span> <span style="color:#a626a4">void</span> <span style="color:#4078f2">main</span>(String[] args) {
		<span style="color:#986801">AbstractMediator</span> <span style="color:#986801">mediator</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Mediator</span>();
		<span style="color:#a0a1a7"><em>// 采购人员采购电脑</em></span>
		System.out.println(<span style="color:#50a14f">"------采购人员采购电脑--------"</span>);
		<span style="color:#986801">Purchase</span> <span style="color:#986801">purchase</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Purchase</span>(mediator);
		purchase.buyIBMcomputer(<span style="color:#986801">100</span>);
		<span style="color:#a0a1a7"><em>// 销售人员销售电脑</em></span>
		System.out.println(<span style="color:#50a14f">"\n------销售人员销售电脑--------"</span>);
		<span style="color:#986801">Sale</span> <span style="color:#986801">sale</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Sale</span>(mediator);
		sale.sellIBMComputer(<span style="color:#986801">1</span>);
		<span style="color:#a0a1a7"><em>// 库房管理人员管理库存</em></span>
		System.out.println(<span style="color:#50a14f">"\n------库房管理人员清库处理--------"</span>);
		<span style="color:#986801">Stock</span> <span style="color:#986801">stock</span> <span style="color:#ab5656">=</span> <span style="color:#a626a4">new</span> <span style="color:#4078f2">Stock</span>(mediator);
		stock.clearStock();
	}
}

</code></span></span>

在多个对象依赖的情况下,通过加入中介者角色,取消了多个对象的关联或依赖关系, 减少了对象的耦合性。

中介者模式的优缺点

中介者模式的主要优点如下:

  • 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间 的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相 对简单的星型结构。
  • 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改 变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭 原则”。
  • 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只 需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。

中介者模式的主要缺点如下:

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

中介者模式适用场景

在以下情况下可以考虑使用中介者模式:

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体 中介者类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值