概念
中介者模式又叫做调停者模式,即在一个环境中,每个元素都是相互有影响的,而且是相互依赖的,加入一个中介者,使每个元素只用处理好属于自己的那部分,每个元素之间的关系处理则是由这个中介者来完成。
介绍
适用场景:中介者模式是一个非常好的封装模式,也是一个很容易被滥用的模式,所以以下情况适合使用中介者模式:
- 多个对象之间产生了相互的依赖关系,并且存在的是相互依赖的关系
- 多个对象的依赖的行为尚不确定或者有发生改变的可能,在这种情况下一般建议采用中介者模式,降低变更引起的风险扩散
优点:减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然也同时减低了类间的耦合
缺点:中介者会膨胀的很大,而且逻辑会很复杂,因为所有的原本 N 个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就复杂
实现
假设场景:一家汽车公司,要想盈利,必须控制好销售、生产、库存管理三大模块,当销量提高了,先查看一番库存,再进行生产,防止生产过剩的问题发生,如果销量过低,而且库存还有很多,则降价促销,减少生产和库存。
首先来声明销售模块:
public class Sale {
//返回销售情况
public int getSalesStatus() {
//销售情况为一个0-200的随机数,当销售情况大于库存量时,大于库存的那部分为预定单
Random random = new Random(System.currentTimeMillis());
int saleStatus = random.nextInt(200);
return saleStatus;
}
//通知销售部门大力促销
public void blockBuster() {
//实例化仓库
Store store = new Store();
//查询仓库的量,并全拿来促销
int repertory = store.getRepertory();
//清库
store.reduce(repertory);
System.out.println("大型促销活动,共销售:" + repertory + "台");
}
//接到大订单的时候
public void bigOrder(int num){
//实例化仓库
Store store = new Store();
//实例化工厂
Produce produce = new Produce();
//查询当前库存
int repertory = store.getRepertory();
if(num > repertory){
store.reduce(repertory);
produce.urgentCreate(num - repertory);
}else{
store.reduce(num);
produce.create(20);
}
}
}
声明生产模块:
public class Produce {
//定义工厂加急生产的数目
public void urgentCreate(int num){
System.out.println("紧急生产" + num + "台");
}
//停止生产
public void stop(){
System.out.println("我们放假了!");
}
//普通生产
public void create(int num) {
//实例仓库
Store store = new Store();
//实例销售情况
Sale sale = new Sale();
//查询汽车的销售情况
int buy = sale.getSalesStatus();
if(buy > 100){
//当销售情况大于100时,需要在原来的生产计划上增产num台
store.add(num);
}else{
//当销售情况小于等于100的时候,需要在原来的生产计划上减产一半
int half = num / 2;
store.add(half);
}
//查看库存余量
int total = store.getRepertory();
System.out.println("库存余量为:" + total);
}
}
声明库存模块:
public class Store {
//初始化库存为100台
private static int NUMBER = 100;
//增加库存
public void add(int num){
NUMBER += num;
System.out.println("库存增加:" + num);
}
//减少库存
public void reduce(int num){
NUMBER -= num;
System.out.println("库存减少:" + num);
}
//返回库存数量
public int getRepertory(){
return NUMBER;
}
//当库存量达到仓库容量的时候,通知销售部门加大力度促销,通知生产部门停止生产
public void max(){
//实例化生产部门
Produce produce = new Produce();
//实例化销售部门
Sale sale = new Sale();
//生产部门停止生产
produce.stop();
//通知销售部门大力促销
sale.blockBuster();
}
}
定义客户端测试:
public class Client {
public static void main(String[] args) {
//进行大订单
Sale sale = new Sale();
System.out.println("大订单为140台");
sale.bigOrder(140);
System.out.println("__________________");
//生产商普通生产
Produce produce = new Produce();
produce.create(50);
System.out.println("__________________");
//库存挤满了
Store store = new Store();
store.max();
System.out.println("__________________");
}
}
测试结果:
由上面的代码可以发现,生产模块,销售模块,库存模块三个模块两两相互制约,当库存小于大订单的量的时候,就要进行紧急生产,而库存量到达最大容量的时候,就要停止生产,进行大促销。这个案例也是相对比较简单的,当模块的数量增多的时候,就会发现,代码的逻辑显得十分复杂,假如添加一个模块进去,就要到每个模块中进行修改,于是引入了中介者模式,就是模块只用负责自己的事情就行,他们模块之间的关系由这个中介者来完成,相当于下图的逻辑:
以下是对上面的案例使用中介者模式进行修改:
首先声明中介者接口:
/**
* 把中介者抽象定义
*/
public abstract class AbstractMediator {
protected Produce produce;
protected Store store;
protected Sale sale;
public AbstractMediator() {
produce = new Produce(this);
store = new Store(this);
sale = new Sale(this);
}
//声明方法处理多个对象之间的关系
public abstract void execute(String str,Object...objects);
}
然后完成中介者的具体实现,这里填写的时各个模块之间的关系处理
public class Mediator extends AbstractMediator {
//完成方法的实现
@Override
public void execute(String str, Object... objects) {
if(str.equals("BigOrder")){
this.bigOrder((Integer)objects[0]);
}else if(str.equals("Create")){
this.create((Integer)objects[0]);
}else if(str.equals("IsFull")){
this.max();
}else if(str.equals("GoodSale")){
this.blockBuster();
}
}
//普通生产
private void create(int num) {
//查询汽车的销售情况
int buy = super.sale.getSalesStatus();
if(buy > 100){
//当销售情况大于100时,需要在原来的生产计划上增产num台
store.add(num);
}else{
//当销售情况小于等于100的时候,需要在原来的生产计划上减产一半
int half = num / 2;
store.add(half);
}
//查看库存余量
int total = store.getRepertory();
System.out.println("库存余量为:" + total);
}
//当库存量达到仓库容量的时候,通知销售部门加大力度促销,通知生产部门停止生产
private void max(){
//生产部门停止生产
produce.stop();
//通知销售部门大力促销
sale.blockBuster();
}
//通知销售部门大力促销
private void blockBuster() {
//查询仓库的量,并全拿来促销
int repertory = super.store.getRepertory();
//清库
store.reduce(repertory);
System.out.println("大型促销活动,共销售:" + repertory + "台");
}
//接到大订单的时候
private void bigOrder(int num){
//查询当前库存
int repertory = super.store.getRepertory();
if(num > repertory){
store.reduce(repertory);
produce.urgentCreate(num - repertory);
}else{
store.reduce(num);
produce.create(20);
}
}
}
然后声明一个中介者关系类,因为在普通项目中可能存在多个中介者,这个类就是处理中介者之间的关系的
public abstract class AbstractColleague {
protected AbstractMediator mediator;
public AbstractColleague(AbstractMediator abstractMediator){
this.mediator = abstractMediator;
}
}
然后对三个模块的代码进行修改,每个模块只用实现自己的部分
生产模块:
public class Produce extends AbstractColleague{
public Produce(AbstractMediator abstractMediator) {
super(abstractMediator);
}
//定义工厂加急生产的数目
public void urgentCreate(int num){
System.out.println("紧急生产" + num + "台");
}
//停止生产
public void stop(){
System.out.println("我们放假了!");
}
//普通生产
public void create(int num) {
super.mediator.execute("Create",num);
}
}
销售模块:
public class Sale extends AbstractColleague{
public Sale(AbstractMediator abstractMediator) {
super(abstractMediator);
}
//返回销售情况
public int getSalesStatus() {
//销售情况为一个0-200的随机数,当销售情况大于库存量时,大于库存的那部分为预定单
Random random = new Random(System.currentTimeMillis());
int saleStatus = random.nextInt(200);
return saleStatus;
}
//通知销售部门大力促销
public void blockBuster() {
super.mediator.execute("GoodSale");
}
//接到大订单的时候
public void bigOrder(int num){
super.mediator.execute("BigOrder",num);
}
}
库存模块:
public class Store extends AbstractColleague{
//初始化库存为100台
private static int NUMBER = 100;
public Store(AbstractMediator abstractMediator) {
super(abstractMediator);
}
//增加库存
public void add(int num){
NUMBER += num;
System.out.println("库存增加:" + num);
}
//减少库存
public void reduce(int num){
NUMBER -= num;
System.out.println("库存减少:" + num);
}
//返回库存数量
public int getRepertory(){
return NUMBER;
}
//当库存量达到仓库容量的时候,通知销售部门加大力度促销,通知生产部门停止生产
public void max(){
super.mediator.execute("IsFull");
}
}
客户端进行测试:
public class Client {
public static void main(String[] args) {
AbstractMediator abstractMediator = new Mediator();
//进行大订单
Sale sale = new Sale(abstractMediator);
System.out.println("大订单为140台");
sale.bigOrder(140);
System.out.println("__________________");
//生产商普通生产
Produce produce = new Produce(abstractMediator);
produce.create(50);
System.out.println("__________________");
//库存挤满了
Store store = new Store(abstractMediator);
store.max();
System.out.println("__________________");
}
}
实验结果:
本文的代码:https://pan.baidu.com/s/19NH5ikt9yHwDVg0Vtz5kmA
提取码:3zya