設計模式11—設計模式之中介者模式(Mediator)(行為型)

來源:互聯網
上載者:User
1.情境問題

電腦中如果沒有主板,那麼就會出現如所示的亂成一團的結構。

 
如果上面的情況發生在軟體開發呢?
如果軟體開發需要很多模組,難道要每個模組同其他模組各個互動嗎?那豈不是太不好用嗎?那麼如何簡化這種互動呢?跟電腦一樣,弄一個中介者就行了。所有的模組跟中介者互動,那麼就降低了模組間的耦合性。
2.舉一個稍微具體的例子

使用電腦看電影:
首先是光碟機讀取光碟片資料,告訴主板,狀態改變
主辦得到資料,交給CPU處理
CPU處理完,把資料分為視頻和音頻,通知主板,它處理完了。
主板去得到CPU處理過後的資料,把資料交給顯卡和音效卡,然後顯示出視頻和發出聲音。
3.解決方案:中介者模式3.1中介者定義:

用一個中介對象來封裝一系列的對象互動,中介者使得各對象不需要顯示的相互引用,從而使其耦合鬆散,而且可以獨立的改變他們之間的互動。這樣會有利於對象的修改和維護。
3.2中介者結構圖:

 
4.範例程式碼如下4.1同事類的抽象父類(注意是個抽象類別)

package demo09.mediator.example1;/** * 同事類的抽象父類 */public abstract class Colleague {/** * 持有中介者對象,每一個同事類都知道它的中介者對象 */private Mediator mediator;/** * 構造方法,傳入中介者對象 *  * @param mediator *        中介者對象 */public Colleague(Mediator mediator) {this.mediator = mediator;}/** * 擷取當前同事類對應的中介者對象 *  * @return 對應的中介者對象 */public Mediator getMediator() {return mediator;}}
4.2同事A注意:是繼承奧
package demo09.mediator.example1;/** * 具體的同事類A */public class ConcreteColleagueA extends Colleague {public ConcreteColleagueA(Mediator mediator) {super(mediator);}/** * 示意方法,執行某些業務功能 */public void someOperation() {//在需要跟其他同事通訊的時候,通知中介者對象getMediator().changed(this);}}
4.3同事B注意:是繼承
package demo09.mediator.example1;/** * 具體的同事類B */public class ConcreteColleagueB extends Colleague {public ConcreteColleagueB(Mediator mediator) {super(mediator);}/** * 示意方法,執行某些業務功能 */public void someOperation() {//在需要跟其他同事通訊的時候,通知中介者對象getMediator().changed(this);}}
4.4中介者,定義各個同事對象通訊的介面
package demo09.mediator.example1;/** * 中介者,定義各個同事對象通訊的介面 */public interface Mediator {/** * 同事對象在自身改變的時候來通知中介者的方法, * 讓中介者去負責相應的與其他同事對象的互動 * @param colleague 同事對象自身,好讓中介者對象通過對象執行個體 *                  去擷取同事對象的狀態 */public void changed(Colleague colleague);}
4.5具體的中介者實現

所有的同事互動都是在中介者中實現

package demo09.mediator.example1;/** * 具體的中介者實現 */public class ConcreteMediator implements Mediator {/** * 持有並維護同事A */private ConcreteColleagueA colleagueA;/** * 持有並維護同事B */private ConcreteColleagueB colleagueB;/** * 設定中介者需要瞭解並維護的同事A對象 * @param colleague 同事A對象 */public void setConcreteColleagueA(ConcreteColleagueA colleague) {colleagueA = colleague;}/** * 設定中介者需要瞭解並維護的同事B對象 * @param colleague 同事B對象 */public void setConcreteColleagueB(ConcreteColleagueB colleague) {colleagueB = colleague;}public void changed(Colleague colleague) {//某個同事類發生了變化,通常需要與其他同事交戶//具體協調相應的同事對象來實現協作行為}}
5.使用中介者實現範例:5.1結構

 
5.2同事類的抽象父類(注意:是個抽象類別)

package demo09.mediator.example2;/** * 同事類的抽象父類 */public abstract class Colleague {/** * 持有中介者對象,每一個同事類都知道它的中介者對象 */private Mediator mediator;/** * 構造方法,傳入中介者對象 * @param mediator 中介者對象 */public Colleague(Mediator mediator) {this.mediator = mediator;}/** * 擷取當前同事類對應的中介者對象 * @return 對應的中介者對象 */public Mediator getMediator() {return mediator;}}
5.3光碟機類,一個同事類
package demo09.mediator.example2;/** * 光碟機類,一個同事類 */public class CDDriver extends Colleague{public CDDriver(Mediator mediator) {super(mediator);}/** * 光碟機讀取出來的資料 */private String data = "";/** * 擷取光碟機讀取出來的資料 * @return 光碟機讀取出來的資料 */public String getData(){return this.data;}/** * 讀取光碟片 */public void readCD(){//逗號前是視頻顯示的資料,逗號後是聲音this.data = "設計模式,值得好好研究";//通知主板,自己的狀態發生了改變this.getMediator().changed(this);}}
5.4CPU類,一個同事類
package demo09.mediator.example2;/** * CPU類,一個同事類 */public class CPU extends Colleague{public CPU(Mediator mediator) {super(mediator);}/** * 分解出來的視頻資料 */private String videoData = "";/** * 分解出來的聲音資料 */private String soundData = "";/** * 擷取分解出來的視頻資料 * @return 分解出來的視頻資料 */public String getVideoData() {return videoData;}/** * 擷取分解出來的聲音資料 * @return 分解出來的聲音資料 */public String getSoundData() {return soundData;}/** * 處理資料,把資料分成音頻和視頻的資料 * @param data 被處理的資料 */public void executeData(String data){//把資料分解開,前面的是視頻資料,後面的是音頻資料String [] ss = data.split(",");this.videoData = ss[0];this.soundData = ss[1];//通知主板,CPU的工作完成this.getMediator().changed(this);}}
5.5顯卡類,一個同事類
package demo09.mediator.example2;/** * 顯卡類,一個同事類 */public class VideoCard extends Colleague {public VideoCard(Mediator mediator) {super(mediator);}/** * 顯示視頻資料 *  * @param data *        被顯示的資料 */public void showData(String data) {System.out.println("您正觀看的是:" + data);}}
5.6音效卡類,一個同事類
package demo09.mediator.example2;/** * 音效卡類,一個同事類 */public class SoundCard extends Colleague{public SoundCard(Mediator mediator) {super(mediator);}/** * 按照聲頻資料發出聲音 * @param data 發出聲音的資料 */public void soundData(String data){System.out.println("畫外音:"+data);}}
5.7中介者介面
package demo09.mediator.example2;/** * 中介者對象的介面 */public interface Mediator {/** * 同事對象在自身改變的時候來通知中介者的方法, * 讓中介者去負責相應的與其他同事對象的互動 * @param colleague 同事對象自身,好讓中介者對象通過對象執行個體 *                  去擷取同事對象的狀態 */public void changed(Colleague colleague);}
5.8主板類,實現中介者介面
package demo09.mediator.example2;/** * 主板類,實現中介者介面 */public class MotherBoard implements Mediator{/** * 需要知道要互動的同事類——光碟機類 */private CDDriver cdDriver = null;/** * 需要知道要互動的同事類——CPU類 */private CPU cpu = null;/** * 需要知道要互動的同事類——顯卡類 */private VideoCard videoCard = null;/** * 需要知道要互動的同事類——音效卡類 */private SoundCard soundCard = null;public void setCdDriver(CDDriver cdDriver) {this.cdDriver = cdDriver;}public void setCpu(CPU cpu) {this.cpu = cpu;}public void setVideoCard(VideoCard videoCard) {this.videoCard = videoCard;}public void setSoundCard(SoundCard soundCard) {this.soundCard = soundCard;}public void changed(Colleague colleague) {if(colleague == cdDriver){//表示光碟機讀取資料了this.opeCDDriverReadData((CDDriver)colleague);}else if(colleague == cpu){//表示CPU處理完了this.opeCPU((CPU)colleague);}}/** * 處理光碟機讀取資料過後與其他對象的互動 * @param cd 光碟機同事對象 */private void opeCDDriverReadData(CDDriver cd){//1:先擷取光碟機讀取的資料String data = cd.getData();//2:把這些資料傳遞給CPU進行處理this.cpu.executeData(data);}/** * 處理CPU處理完資料後與其他對象的互動 * @param cpu CPU同事類 */private void opeCPU(CPU cpu){//1:先擷取CPU處理過後的資料String videoData = cpu.getVideoData();String soundData = cpu.getSoundData();//2:把這些資料傳遞給顯卡和音效卡展示出來this.videoCard.showData(videoData);this.soundCard.soundData(soundData);}}
5.9用戶端使用:看電影
package demo09.mediator.example2;public class Client {public static void main(String[] args) {// 1:建立中介者——主板對象MotherBoard mediator = new MotherBoard();// 2:建立同事類CDDriver cd = new CDDriver(mediator);CPU cpu = new CPU(mediator);VideoCard vc = new VideoCard(mediator);SoundCard sc = new SoundCard(mediator);// 3:讓中介者知道所有的同事mediator.setCdDriver(cd);mediator.setCpu(cpu);mediator.setVideoCard(vc);mediator.setSoundCard(sc);// 4:開始看電影,把光碟片放入光碟機,光碟機開始讀盤cd.readCD();}}
6.思考中介者模式6.1中介者模式的功能以及調用順序圖:

封裝對象之間的互動。同事之間是如下互動的。

 
6.2中介者模式的本質

封裝互動
6.3中介者模式的優缺點

優點:鬆散耦合,集中控制互動,多對多變成一對多。
缺點:過度集中化,中介者對象變得很複雜,難於管理和維護。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.