中介者模式——Mediator

案例展示——Mediator怎么用?

 我们先来看这样一种场景:有一家宝马4s店,下面有三个部门:销售部门,采购部门,库存管理部门,这三个部门的职责分别是:

  • 采购部门: 负责宝马汽车的采购。与销售部门沟通销售情况:销售的好多进几辆车,销售不好就少进几辆车;与库存管理部门沟通库存情况:扩大库存或者减少库存

  • 库存管理部门: 负责库存管理。与采购部门沟通采购情况:库存太多少采购,库存太少多采购;与销售部门沟通销售情况:库存积压,倾销处理。

  • 销售部门: 负责销售汽车。与采购部门和库存管理部门进行沟通:根据销售情况决定是否增加库存。

 我们会发现,各个部门之间是相互交叉,相互依赖的,每一个模块都需要另外两个模块的信息支持,耦合度特别的高,现在给出设计的类图如下:

image

代码实现如下:

//采购管理
public class Purchase {
    //采购宝马汽车
    public void buyBaomaCar(int number) {
        //访问库存
        Stock stock = new Stock();
        //访问销售
        Sale sale = new Sale();
        //电脑的销售情况
        int saleStatus = sale.getSaleStatus();
        if (saleStatus > 80) { //销售情况良好
            System.out.println("采购宝马汽车:" + number + "台");
            //库存增加
            stock.increase(number);
        } else { //销售情况不好
            //折半采购
            int buyNumber = number / 2;
            System.out.println("采购宝马汽车:" + buyNumber + "台");
        }
    }

    //不再采购宝马汽车
    public void refuseBuyBaomaCar() {
        System.out.println("不再采购宝马汽车。。。");
    }
}

//库存管理
public class Stock {

    //原始库存是100辆宝马车
    private static int BAOMACAR_NUMBER = 100;

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

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

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

    //存货太多,通知采购人员不要采购,销售人员尽快销售
    public void clearStock() {
        Purchase purchase = new Purchase();
        Sale sale = new Sale();
        System.out.println("清理存货数量为:" + BAOMACAR_NUMBER);
        //要求销售人员折价销售
        sale.offSale();
        //要求采购人员不要采购
        purchase.refuseBuyBaomaCar();
    }
}

//销售管理
public class Sale {

    //销售宝马汽车
    public void sellBaomaCar(int number) {
        //访问库存
        Stock stock = new Stock();
        //访问采购人员
        Purchase purchase = new Purchase();
        //库存不够销售,通知采购人员采购宝马汽车
        if (stock.getStockNumber() < number) {
            purchase.buyBaomaCar(number);
        }
        System.out.println("销售宝马汽车:" + number + "台");
        stock.decrease(number);
    }

    //反馈销售情况
    public int getSaleStatus() {
        Random random = new Random(System.currentTimeMillis());
        int saleStatus = random.nextInt(100);
        System.out.println("宝马汽车的销售情况为:" + saleStatus);
        return saleStatus;
    }

    //折价处理
    public void offSale() {
        //清理所有库存
        Stock stock = new Stock();
        System.out.println("半价销售宝马汽车" + stock.getStockNumber() + "台");
    }
}

//在一个场景中运行得:
public class Client {
    public static void main(String[] args) {
        System.out.println("======采购人员采购宝马汽车======");
        Purchase purchase = new Purchase();
        purchase.buyBaomaCar(100);

        System.out.println("======销售人员销售宝马汽车=======");
        Sale sale = new Sale();
        sale.sellBaomaCar(12);

        System.out.println("======库房管理人员管理库存=======");
        Stock stock = new Stock();
        stock.clearStock();
    }
}

//结果如下:
======采购人员采购宝马汽车======
宝马汽车的销售情况为:22
采购宝马汽车:50======销售人员销售宝马汽车=======
销售宝马汽车:12台
库存数量为:88
======库房管理人员管理库存=======
清理存货数量为:88
半价销售宝马汽车88台
不再采购宝马汽车。。。

 虽然我们顺利的实现了功能,可是这样的设计有没有问题?肯定是有很大的问题的,前面已经说过,耦合度太高,每个类之间依赖太深,可扩展性太低。假如再加一个部门,比如说是监管部门,监管部门需要获取每个部门的情况,每个部门又要获得监管部门的反馈信息,那样所有的类都需要修改,类图之间出现蜘蛛网状结构,这种设计是很不合理的,如下图所示:

image

 基于上述的情况,我们可以引入一个中间管理者对每个类之间的依赖进行管理。每个模块之间不再相互交流,要交流就通过中间管理者进行交流,每个模块只负责自己的业务逻辑,不属于自己的则丢给中间管理者来处理,如下图所示:

image

对上面的案例进行修改,下面是设计类图:

image

  • AbstractMediator:抽象的中介者,实现中介者的抽象定义。定义了一个事件方法execute()

  • Mediator:具体的中介者,实现了AbstractMediator中的execute()事件方法。可以根据业务的要求产生多个中介者,并划分中介者的职责。中介者中一般定义多个private方法,用来处理各个对象之间的依赖关系。

  • AbstractColleague:抽象同事类,可以让具体的实现类继承

下面是代码实现:

//抽象的中介者
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);
}

//具体中介者
public class Mediator extends AbstractMediator {

    //事件方法
    public void execute(String str, Object...objects) {
        if (str.equals("purchase.buy")) { //采购宝马汽车
            this.buyBaomaCar((Integer)objects[0]);
        } else if (str.equals("sale.sell")) { //销售宝马汽车
            this.sellBaomaCar((Integer)objects[0]);
        } else if (str.equals("sale.offsell")) { //折价销售
            this.offSell();
        } else if (str.equals("stock.clear")) { //清仓处理
            this.clearStock();
        }
    }

    //采购宝马汽车
    private void buyBaomaCar(int number) {
        int saleStatus = super.sale.getSaleStatus();
        if (saleStatus > 80) { //销售情况良好
            System.out.println("采购宝马汽车:"  + number + "台");
            //库存增加
            super.stock.increase(number);
        } else { //销售情况不好
            //折半采购
            int buyNumber = number / 2;
            System.out.println("采购宝马汽车:"  + buyNumber + "台");
        }
    }

    //销售宝马汽车
    private void sellBaomaCar(int number) {
        //库存不够销售,通知采购人员采购宝马汽车
        if (super.stock.getStockNumber() < number) {
            super.purchase.buyBaomaCar(number);
        }
        super.stock.decrease(number);
    }

    //折价销售
    private void offSell() {
        System.out.println("半价销售宝马汽车" + stock.getStockNumber() + "台");
    }

    //清仓处理
    private void clearStock() {
        //要求清仓销售
        super.sale.offSale();
        //要求采购人员不要采购
        super.purchase.refuseBuyBaomaCar();
    }
}

//抽象的同事类
public abstract class AbstractColleague {
    protected AbstractMediator mediator;
    public AbstractColleague(AbstractMediator mediator) {
        this.mediator = mediator;
    }
}

//采购管理
public class Purchase extends AbstractColleague{

    //构造函数
    public Purchase(AbstractMediator mediator) {
        super(mediator);
    }

    //采购宝马汽车
    public void buyBaomaCar(int number) {
      super.mediator.execute("purchase.buy", number);
    }

    //不再采购宝马汽车
    public void refuseBuyBaomaCar() {
        System.out.println("不再采购宝马汽车。。。");
    }
}

//库存管理
public class Stock extends AbstractColleague {

    //原始库存是100辆宝马车
    private static int BAOMACAR_NUMBER = 100;

    public Stock(AbstractMediator mediator) {
        super(mediator);
    }

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

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

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

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

//销售管理
public class Sale extends AbstractColleague{

    public Sale(AbstractMediator mediator) {
        super(mediator);
    }

    //销售宝马汽车
    public void sellBaomaCar(int number) {
      super.mediator.execute("sale.sell", number);
        System.out.println("销售宝马汽车:" + number + "台");
    }

    //反馈销售情况
    public int getSaleStatus() {
        Random random = new Random(System.currentTimeMillis());
        int saleStatus = random.nextInt(100);
        System.out.println("宝马汽车的销售情况为:" + 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.buyBaomaCar(100);

        System.out.println("======销售人员销售电脑======");
        Sale sale = new Sale(mediator);
        sale.sellBaomaCar(1);

        System.out.println("======库房管理人员管理库存======");
        Stock stock = new Stock(mediator);
        stock.clearStock();
    }
}

//结果如下:
======采购人员采购电脑=====
宝马汽车的销售情况为:27
采购宝马汽车:50======销售人员销售电脑======
库存数量为:99
销售宝马汽车:1======库房管理人员管理库存======
清理存货数量为:99
半价销售宝马汽车99台
不再采购宝马汽车。。。

 加入一个中介者,将与自己无关的活动交给中介者进行处理,设计结构更加清晰,而且类与类之间的耦合性大大减少,可扩展性大大增强。

深入分析——Mediator是什么?

Mediator的定义

定义: 用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变它们之间的交互。如下是通用类图:

image

  • Mediator抽象中介者角色: 定义统一的接口,用于各同事角色之间的交互

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

  • Colleague同事角色: 通过中介者与其他同事角色进行通信。每个同事类的行为分为两种:

    • 第一种:自己本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其他的同时类或中介者没有任何的依赖
    • 第二种:必须依赖中介者才能完成的行为,叫做依赖方法
Mediator的应用

 中介者模式适用于对象之间紧密耦合的情况,紧密耦合的标准是:在类图之间出现可蜘蛛网状结构。

参考

《设计模式之禅》

猜你喜欢

转载自blog.csdn.net/king123456man/article/details/82849682