設計模式之中介者模式

        中介者模式又叫調停模式,定義如下:用一箇中介者對象封裝一系列的對象的交互,中介者使各個對象不需要顯示的相互作用,從而使其耦合鬆散,而且可以獨立的改變他們之間的交互。

 

通用類圖如下:

 



 

從圖中可以看到,中介者模式由一下幾部分組成:

1.抽象中介者模式Mediator

抽象中介模式定義統一的接口,用於各同事角色之間的通信

 

2.具體中介者模式ConcreteMediator

具體中介者角色通過協調各個同事角色實現協作行爲,因此它必須依賴於各個同事角色

 

3.同事角色Colleague

每一個同事角色都知道中介者角色,而且其他的同事角色通信的時候,一定要通過中介角色的協作

 

說完中介者的通用類圖,下面看看如何應用以及應用中介者模式有哪些好處

現實生活中存在很多的中介者模式,比如和我們自身相關的那就是租房,大家從學校畢業來到社會上工作的第一件事可能就是租房(有房的除外),然後纔是找工作,還有就是機場的調度中心其實也是一箇中介者模式的體現,還有我們做開發現在用的最多一種結構MVC也是中介模式的體現,其中C叫做控制器,V--視圖,M--業務邏輯,前端想要顯示什麼數據首先會詢問C然後又C去詢問M而不是通過V直接詢問M,這樣的設計就是爲了鬆耦合,這也是中介者模式的優點,下面我們以一個實際應用來說明:

 

一家奔馳的4S店主要設計到的角色有:銷售部門、採購部門、庫存部門

 

銷售部門:

銷售部門要反饋銷售情況,暢銷就多采購,不暢銷就少採購,同事賣出後要通知庫存部門

 

庫存部門:

即使是暢銷情況,如果庫存已經超過某個上限也就不需要在採購了

 

 下面是沒有使用中介者模式的類圖


 
 

 

/**
 * 銷售部門
 * 
 */
public class Sale {

    // 銷售奔馳汽車
    public void sellBenz(int carNum) {

        // 訪問庫存
        Stock stock = new Stock();
        // 判斷購買量和庫存量
        if (stock.getStockNum() < carNum) {
            // 庫存不夠,通知採購部門進行採購
            Purchase purchase = new Purchase();

            purchase.buyBenz(carNum);
        }
        System.out.println("銷售汽車:" + carNum + "輛");
        // 更新庫存
        stock.decrease(carNum);
    }

    // 打折銷售
    public void offSale() {

        // 訪問庫存
        Stock stock = new Stock();

        System.out.println("打折處理汽車數量:" + stock.getStockNum());
    }

    // 獲取銷售狀態,用數字0-10來表示,0沒有銷售,10代表非常暢銷
    public int getSaleStatus() {

        Random random = new Random(System.currentTimeMillis());

        int saleStatus = random.nextInt(10);

        System.out.println("汽車的銷售情況:" + saleStatus);

        return saleStatus;
    }
}

 

/**
 * 採購部門
 * 
 */
public class Purchase {

    // 採購奔馳汽車
    public void buyBenz(int carNum) {

        // 詢問銷售部門汽車的銷售情況,如果銷售狀態>8則進行採購,如果是0就暫時不採購,如果處於0--8之間則進行折半採購
        Sale sale = new Sale();
        if (sale.getSaleStatus() == 0) {
            System.out.println("銷售情況不好,暫時不採購");
        } else if (sale.getSaleStatus() < 8) {
            int halfNum = carNum / 2;
            System.out.println("銷售情況不算理想,進行折半採購,採購汽車數量:" + halfNum);
            // 更新庫存
            Stock stock = new Stock();
            stock.increase(halfNum);

        } else {
            System.out.println("採購汽車:" + carNum + "量");
            // 更新庫存
            Stock stock = new Stock();
            stock.increase(carNum);
        }
    }

    // 不在採購
    public void refuseBuyBenz() {

        System.out.println("不在採購汽車");
    }
}

 

/**
 * 庫存部門
 * 
 */
public class Stock {

    // 庫存中默認100輛奔馳
    public static int DEFAULT_NUM = 100;

    // 庫存汽車容量的上限
    public static final int MAX_NUM = 200;

    // 增加庫存
    public void increase(int carNum) {

        DEFAULT_NUM += carNum;

        System.out.println("現在庫存量:" + DEFAULT_NUM);
    }

    // 減少庫存
    public void decrease(int catNum) {

        DEFAULT_NUM -= catNum;

        System.out.println("現在庫存剩餘量:" + DEFAULT_NUM);
    }

    // 獲取庫存量
    public int getStockNum() {

        return DEFAULT_NUM;
    }

    // 清理庫存
    public void clearStock() {

        // 通知銷售
        Sale sale = new Sale();

        sale.offSale();

        // 通知採購
        Purchase purchase = new Purchase();

        purchase.refuseBuyBenz();
    }
}

 

public class Client {

    public static void main(String[] args) {

        // 採購人員採購汽車
        System.out.println("-----採購汽車------");
        Purchase purchase = new Purchase();
        purchase.buyBenz(20);

        // 銷售人員銷售汽車
        System.out.println("-----銷售汽車------");
        Sale sale = new Sale();
        sale.sellBenz(50);

        // 清理庫存
        System.out.println("-----清理庫存-------");
        Stock stock = new Stock();
        stock.clearStock();
    }

}

 

相信大家已經看出這段程序的問題,那就是銷售、採購、庫存之間耦合太緊了,稍微有一個程序需要修改,那麼可能就會導致一片程序的修改,下面看看引入中介者模式之後的效果:

 



 

/**
 * 抽象中介者
 * 
 */
public abstract class AbstractMediator {

    protected Sale sale;

    protected Purchase purchase;

    protected Stock stock;

    public AbstractMediator() {

        sale = new Sale(this);
        purchase = new Purchase(this);
        stock = new Stock(this);
    }

    protected abstract void exec(String str, Integer... num);
}

 

/**
 * 
 * 具體中介者
 */
public class Mediator extends AbstractMediator {
    

    /**
     * @param str
     * @param num
     */
    @Override
    protected void exec(String str, Integer... num) {

        if ("buy".equals(str)) {
            this.buyBenz(num[0]);
        }

        if ("sell".equals(str)) {

            this.sellBenz(num[0]);
        }

        if ("offSale".equals(str)) {

            this.offSale();
        }

        if ("clear".equals(str)) {

            this.clearStock();
        }
    }

    // 清理庫存
    public void clearStock() {

        // 通知銷售
        super.sale.offSale();

        // 通知採購
        super.purchase.refuseBuyBenz();
    }

    // 打折銷售
    private void offSale() {

        // 訪問庫存

        System.out.println("打折處理汽車數量:" + super.stock.getStockNum());
    }

    // 採購奔馳汽車
    private void buyBenz(int carNum) {

        // 詢問銷售部門汽車的銷售情況,如果銷售狀態>8則進行採購,如果是0就暫時不採購,如果處於0--8之間則進行折半採購

        if (super.sale.getSaleStatus() == 0) {
            System.out.println("銷售情況不好,暫時不採購");
        } else if (super.sale.getSaleStatus() < 8) {
            int halfNum = carNum / 2;
            System.out.println("銷售情況不算理想,進行折半採購,採購汽車數量:" + halfNum);
            // 更新庫存
            super.stock.increase(halfNum);

        } else {
            System.out.println("採購汽車:" + carNum + "量");
            // 更新庫存
            super.stock.increase(carNum);
        }
    }

    // 銷售奔馳汽車
    private void sellBenz(int carNum) {

        // 訪問庫存
        // 判斷購買量和庫存量
        if (super.stock.getStockNum() < carNum) {
            // 庫存不夠,通知採購部門進行採購

            super.purchase.buyBenz(carNum);
        }
        System.out.println("銷售汽車:" + carNum + "輛");
        // 更新庫存
        super.stock.decrease(carNum);
    }

}

 

/**
 * 抽象同事類
 * 
 */
public abstract class AbstractColleague {

    protected AbstractMediator mediator;

    public AbstractColleague(AbstractMediator mediator) {

        this.mediator = mediator;
    }
}

 

/**
 * 銷售部門
 * 
 */
public class Sale extends AbstractColleague {

    /**
     * @param mediator
     */
    public Sale(AbstractMediator mediator) {
        super(mediator);
    }

    // 銷售奔馳汽車
    public void sellBenz(int carNum) {

        super.mediator.exec("sell", 50);
    }

    // 打折銷售
    public void offSale() {

        super.mediator.exec("offSale");
    }

    // 獲取銷售狀態,用數字0-10來表示,0沒有銷售,10代表非常暢銷
    public int getSaleStatus() {

        Random random = new Random(System.currentTimeMillis());

        int saleStatus = random.nextInt(10);

        System.out.println("汽車的銷售情況:" + saleStatus);

        return saleStatus;
    }
}

 

/**
 * 庫存部門
 * 
 */
public class Stock extends AbstractColleague {

    /**
     * @param mediator
     */
    public Stock(AbstractMediator mediator) {
        super(mediator);
        // TODO Auto-generated constructor stub
    }

    // 庫存中默認100輛奔馳
    public static int DEFAULT_NUM = 100;

    // 庫存汽車容量的上限
    public static final int MAX_NUM = 200;

    // 增加庫存
    public void increase(int carNum) {

        DEFAULT_NUM += carNum;

        System.out.println("現在庫存量:" + DEFAULT_NUM);
    }

    // 減少庫存
    public void decrease(int catNum) {

        DEFAULT_NUM -= catNum;

        System.out.println("現在庫存剩餘量:" + DEFAULT_NUM);
    }

    // 獲取庫存量
    public int getStockNum() {

        return DEFAULT_NUM;
    }

    // 清理庫存
    public void clearStock() {

        super.mediator.exec("clear", DEFAULT_NUM);
    }
}

 

/**
 * 採購部門
 * 
 */
public class Purchase extends AbstractColleague {

    /**
     * @param mediator
     */
    public Purchase(AbstractMediator mediator) {
        super(mediator);
    }

    // 採購奔馳汽車
    public void buyBenz(int carNum) {

        super.mediator.exec("buy", 20);
    }

    // 不在採購
    public void refuseBuyBenz() {

        System.out.println("不在採購汽車");
    }
}

 

public class Client {

    public static void main(String[] args) {

        // 創建一箇中介者
        AbstractMediator mediator = new Mediator();
        // 採購人員採購汽車
        System.out.println("-----採購汽車------");
        Purchase purchase = new Purchase(mediator);
        purchase.buyBenz(20);

        // 銷售人員銷售汽車
        System.out.println("-----銷售汽車------");
        Sale sale = new Sale(mediator);
        sale.sellBenz(50);

        // 清理庫存
        System.out.println("-----清理庫存-------");
        Stock stock = new Stock(mediator);
        stock.clearStock();
    }

}

 

中介者模式簡單,但是簡單並不代表容易使用,而且有時候很容易被誤用,大家可以嘗試在如下情況使用中介者模式:

1.多個對象之間產生了相互依賴的關係

2.多個對象之間有依賴關係,但是依賴行爲尚不確定或者有發生改變的可能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章