設計模式 --- 中介者模式
阿新 • • 發佈:2018-11-22
1.定義
中介者模式包裝了一系列物件相互作用方式,使得這些物件不必相互明顯作用。從而使他們可以鬆耦合。當某些物件之間作用發生改變的時候,不會立即影響其他的一些物件之間的作用。保證這些作用可以彼此獨立變化。中介者模式將多對多的相互作用轉化為一對多的相互作用。中介者模式將物件的行為和協作抽象化,把物件在小尺度的行為上與其他物件的相互作用分開處理。
2.使用場景
當物件之間的互動操作很多且每個物件的行為操作都依賴彼此時,為防止在修改一個物件的行為時,同時涉及修改很多其他物件的行為,可以採用中介者模式來解決緊耦合問題。該模式將物件之間的多對多關係變成一對多關係,中介者物件將系統從網狀結構變成以調停者為中心的星形結構,達到降低系統的複雜性,提高可拓展性的作用。
3.簡單實現
以計算機讀取光碟為例。計算機的主機板連線了CPU、記憶體、顯示卡、IO裝置等,任何兩個模組通訊都是通過主機板來協調,這裡的主機板就是相當於中介者的作用。
//抽象同事物件 abstract class Colleague{ protected Mediator mediator; //每個同事物件都知道中介者 public Colleague(Mediator mediator){ this.mediator = mediator; } } //CPU 負責將主機板傳過來的音視訊解碼 class CPU extends Colleague{ private String dataVideo,dataSound; //視訊和音訊資料 public CPU(Mediator mediator) { super(mediator); } public String getDataVideo() { return dataVideo; } public String getDataSound() { return dataSound; } //資料解碼 public void decodeData(String data){ //分割音視訊資料 String[] tem = data.split(","); dataVideo = tem[0]; dataSound = tem[1]; //告訴中介者狀態改變 mediator.change(this); } } //CD裝置 負責讀取資料 class CDDevice extends Colleague{ private String data; public CDDevice(Mediator mediator) { super(mediator); } //讀取資料 public String read(){ return data; } //載入資料 public void load(){ data = "視訊資料data,音訊資料data"; //模擬資料 //通知中介者 mediator.change(this); } } //顯示卡 負責顯示視訊資料 class GraphicsCard extends Colleague{ public GraphicsCard(Mediator mediator) { super(mediator); } public void showVideo(String data){ System.out.println("視訊顯示:" + data); } } //音效卡 負責音訊播放 class SoundCard extends Colleague{ public SoundCard(Mediator mediator) { super(mediator); } public void palySound(String data){ System.out.println("音訊播放:" + data); } } //抽象中介者 abstract class Mediator{ //同事物件改變時通知中介者方法 //再由中介者通知其它人 abstract void change(Colleague colleague); } //主機板 class MainBoard extends Mediator{ private CPU cpu; private CDDevice cdDevice; private GraphicsCard graphicsCard; private SoundCard soundCard; @Override void change(Colleague colleague) { if (colleague == cdDevice){ //如果是CD裝置讀取了資料 handleCD((CDDevice)colleague); }else if (colleague == cpu){ //如果CPU處理完資料 handleCPU((CPU)colleague); } } //處理cd取得資料後與其他裝置的互動 private void handleCD(CDDevice c){ //交由CPU解碼 cpu.decodeData(c.read()); } //處理CPU處理完資料後與其他裝置的互動 private void handleCPU(CPU cpu){ //交給顯示卡顯示視訊 graphicsCard.showVideo(cpu.getDataVideo()); //交給音效卡播放音訊 soundCard.palySound(cpu.getDataSound()); } public CPU getCpu() { return cpu; } public void setCpu(CPU cpu) { this.cpu = cpu; } public CDDevice getCdDevice() { return cdDevice; } public void setCdDevice(CDDevice cdDevice) { this.cdDevice = cdDevice; } public GraphicsCard getGraphicsCard() { return graphicsCard; } public void setGraphicsCard(GraphicsCard graphicsCard) { this.graphicsCard = graphicsCard; } public SoundCard getSoundCard() { return soundCard; } public void setSoundCard(SoundCard soundCard) { this.soundCard = soundCard; } } public class MediatorMaode { public static void main(String[] args){ //構建一個主機板 MainBoard mainBoard = new MainBoard(); //建立各種裝置 CPU cpu = new CPU(mainBoard); CDDevice cdDevice = new CDDevice(mainBoard); GraphicsCard graphicsCard = new GraphicsCard(mainBoard); SoundCard soundCard = new SoundCard(mainBoard); //設定零件到主機板 mainBoard.setCdDevice(cdDevice); mainBoard.setCpu(cpu); mainBoard.setGraphicsCard(graphicsCard); mainBoard.setSoundCard(soundCard); //播放 cdDevice.load(); } }
輸出:
4.小結
如果依賴關係如網狀比較複雜,可以考慮使用中介者模式進行解耦,但是如果幾個類之間的依賴關係並不複雜,使用中介者模式反而會使邏輯結構變得複雜。