1

前言

由于最近疯狂加班,博客都停更许久,难过~.~

中介者模式定义

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变他们之间的交互。

uml类图

Center

代码分析

我们来模仿一个进销存系统,主要有三个部分,销售、库存和进货。

/**
 * 采购管理,主要负责是否采购糖果
 */
public class CandyPurchase {

    public void buyCandy(int number){
        CandySale candySale = new CandySale();
        CandyStock candyStock = new CandyStock();
        if (candySale.getSaleStauts()>6){
            candyStock.addStock(number);
            System.out.println("采购糖果"+number+"颗");
        }else {
            candyStock.addStock(number/2);
            System.out.println("采购糖果"+number/2+"颗");
        }
        System.out.println("库存"+CandyStock.stockNum+"颗");
    }

    public void refuseBuyCandy(){
        System.out.println("拒绝进货");
    }
}
/**
 * 销售类:
 */
public class CandySale {

    public void saleCandy(int num){
        while (CandyStock.stockNum<num){
            CandyPurchase candyPurchase = new CandyPurchase();
            candyPurchase.buyCandy(100);
            System.out.println("库存数量不够,已购100颗糖 ");
        }
        CandyStock candyStock = new CandyStock();
        candyStock.subtractStock(num);
        System.out.println("卖出"+num+"颗糖");
    }

    //打折销售
    public void discountSale(){
        System.out.println("打折销售糖果"+CandyStock.stockNum+"颗");
    }

    //获得最近的销售状态,0-10,越大越好卖
    public int getSaleStauts(){
        Random random = new Random();
        return random.nextInt(10);
    }
}
//库存
public class CandyStock {
    //库存数量
    protected static int stockNum =1000;

    public synchronized void addStock(int num){
        stockNum+=num;
    }

    public synchronized void subtractStock(int num){
        stockNum-=num;
    }

    public void clearStock(){
        System.out.println("马上年底了,清仓大甩卖了");
        CandyPurchase candyPurchase = new CandyPurchase();
        candyPurchase.refuseBuyCandy();

        CandySale candySale = new CandySale();
        candySale.discountSale();
    }
}
public class Client {
    public static void main(String[] args) {

        System.out.println("-----采购糖果-----");
        CandyPurchase candyPurchase = new CandyPurchase();
        candyPurchase.buyCandy(666);

        System.out.println("-----销售糖果-----");
        CandySale candySale = new CandySale();
        candySale.saleCandy(20);
        System.out.println("-----清库处理-----");
        CandyStock candyStock = new CandyStock();
        candyStock.clearStock();
    }
}
测试结果:
-----采购糖果-----
采购糖果666颗
库存1666颗
-----销售糖果-----
卖出20颗糖
-----清库处理-----
马上年底了,清仓大甩卖了
拒绝进货
打折销售糖果1646颗

结果和我们预期的一致,但我们这三者是彼此关联的,每个类都与其他两个类发生了关系(纯洁点,不要想歪~,~)。迪米特法则认为每个类应只和朋友类交流,而且朋友类并非越多越好,朋友类越多,耦合性越大,修改一个就要从全局考量是否影响到了其他模块,这不是面向对象设计所期望的。让我们用中介者模式把其优化下吧,代码如下:

public abstract class AbstractCandyMediator {
    protected CandyStock candyStock;
    protected CandySale candySale;
    protected CandyPurchase candyPurchase;

    public AbstractCandyMediator() {
        this.candyStock = new CandyStock(this);
        this.candySale = new CandySale(this);
        this.candyPurchase = new CandyPurchase(this);
    }

    public abstract void execute(String type,Object ...objects);

}
public class ConcreteCandyMediator extends AbstractCandyMediator{

    @Override
    public void execute(String type, Object... objects) {
        if (type.equals("buyCandy")){
            this.buyCandy((Integer) objects[0]);
        }else if (type.equals("saleCandy")){
            this.saleCandy((Integer) objects[0]);
        }else {
            this.clearStock();
        }
    }

    private void buyCandy(int num) {
        if (super.candySale.getSaleStauts()>6){
            super.candyStock.addStock(num);
            System.out.println("采购糖果"+ num+"颗");
        }else {
            super.candyStock.addStock(num/2);
            System.out.println("采购糖果"+num /2+"颗");
        }
        System.out.println("库存"+CandyStock.stockNum+"颗");
    }

    public void saleCandy(int num){
        while (CandyStock.stockNum<num){
            buyCandy(100);
            System.out.println("库存数量不够,已购100颗糖 ");
        }
        super.candyStock.subtractStock(num);
        System.out.println("卖出"+num+"颗糖");
    }

    public void clearStock(){
        System.out.println("马上年底了,清仓大甩卖了");
        super.candyPurchase.refuseBuyCandy();
        super.candySale.discountSale();
    }

}
public abstract class AbstractColleague {
    public AbstractCandyMediator mediator;

    public AbstractColleague(AbstractCandyMediator mediator) {
        this.mediator = mediator;
    }
}
public class CandyPurchase extends AbstractColleague {

    public CandyPurchase(AbstractCandyMediator abstractCandyMediator) {
        super(abstractCandyMediator);

    }

    public void buyCandy(int number){
        super.mediator.execute("buyCandy",number);
    }

    public void refuseBuyCandy(){
        System.out.println("拒绝进货");
    }
}
public class CandySale extends AbstractColleague {

    public CandySale(AbstractCandyMediator abstractCandyMediator) {
        super(abstractCandyMediator);

    }

    public void saleCandy(int num){
        super.mediator.execute("saleCandy",num);
    }

    //打折销售
    public void discountSale(){
        System.out.println("打折销售糖果"+CandyStock.stockNum+"颗");
    }

    //获得最近的销售状态,0-10,越大越好卖
    public int getSaleStauts(){
        Random random = new Random();
        return random.nextInt(10);
    }
}
public class CandyStock extends AbstractColleague{
    //库存数量
    protected static int stockNum =1000;

    public CandyStock(AbstractCandyMediator abstractCandyMediator) {
        super(abstractCandyMediator);

    }

    public synchronized void addStock(int num){
        stockNum+=num;
    }

    public synchronized void subtractStock(int num){
        stockNum-=num;
    }

    public void clearStock(){
        super.mediator.execute("123");

    }
}
public class Client {

    public static void main(String[] args) {

        AbstractCandyMediator mediator = new ConcreteCandyMediator();
        CandyPurchase candyPurchase = new CandyPurchase(mediator);
        candyPurchase.buyCandy(666);
        CandySale candySale = new CandySale(mediator);
        candySale.saleCandy(20);
        CandyStock candyStock = new CandyStock(mediator);
        candyStock.clearStock();
    }
}

经过改造,我们发现每个类都只与中介者是朋友类,耦合降低,每个类只处理自己的职责,和其他类有关的统统交给中介者。

中介者模式的应用

中介者模式的优点就是减少类间的依赖,将一对多的依赖变成一对一的依赖,降低耦合,符合迪米特法则。缺点就是中介者会变得异常庞大,逻辑复杂,同事类越多,中介者的逻辑就越复杂。中介者模式适用于多个对象之间出现紧密联系,类图成网状结构,使用中介者模式可以梳理为星型结构,有助于理解其关系。


Alpaca
142 声望33 粉丝