GoF 行為型 中介者模式

中介者模式的定義

用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使得各對(duì)象不需要顯示的相互引用,從而使其松散耦合,而且可以獨(dú)立的改變他們之間的交互。

中介者模式的本質(zhì)

封裝交互。

中介者模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 松散耦合。多個(gè)對(duì)象之間的交互封裝到一個(gè)里面,避免了牽一發(fā)而動(dòng)全身。
    集中控制交互。
  • 多對(duì)多變成一對(duì)多。引入中介者之后,從多對(duì)多變成雙向一對(duì)多。

缺點(diǎn)

  • 太復(fù)雜的中介者會(huì)難以維護(hù)

示例1

public abstract class Colleague {

    /**
     * 持有中介者對(duì)象,每一個(gè)同事類都知道他的中介者對(duì)象
     */
    private Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public Mediator getMediator() {
        return mediator;
    }
}
public class ConcreteColleagueA extends Colleague {

    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }

    /**
     * 示意方法
     */
    public void someOperation() {
        getMediator().changed(this);
    }
}
public class ConcreteColleagueB extends Colleague {

    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }

    /**
     * 示意方法
     */
    public void someOperation() {
        getMediator().changed(this);
    }
}
/**
 * 中介者,定義各個(gè)同事對(duì)象通信的接口
 */
public interface Mediator {

    /**
     * 同時(shí)對(duì)象在自身改變的時(shí)候來通知中介者方法
     * 讓中介者負(fù)責(zé)相應(yīng)的與其他同事對(duì)象的交互
     * @param colleague 同事對(duì)象自身。好讓中介者對(duì)象通過對(duì)象實(shí)例去獲取同事對(duì)象的狀態(tài)。
     */
    void changed(Colleague colleague);
}
public class ConcreteMediator implements Mediator {

    /**持有并維護(hù)同事A*/
    private ConcreteColleagueA colleagueA;
    /**持有并維護(hù)同事B*/
    private ConcreteColleagueB colleagueB;

    @Override
    public void changed(Colleague colleague) {
        //某個(gè)同事對(duì)象發(fā)生了變化,通常是與其他同事對(duì)象交互。
        //具體協(xié)調(diào)相應(yīng)的同事對(duì)象來實(shí)現(xiàn)協(xié)作行為。
    }

    public void setColleagueA(ConcreteColleagueA colleagueA) {
        this.colleagueA = colleagueA;
    }

    public void setColleagueB(ConcreteColleagueB colleagueB) {
        this.colleagueB = colleagueB;
    }
}

示例2

實(shí)際開發(fā)中通常去掉同事對(duì)象的父類。通常不定義Mediator接口,把具體的中介者實(shí)現(xiàn)成單例。同事對(duì)象也不再持有中介者,而是用到就去獲取。中介者也不再持有同事對(duì)象,而是傳參等方式獲取。

public abstract class Colleague {

    //  ~屬性
    //  =========================================

    private Mediator mediator;

    //  ~構(gòu)造器
    //  =========================================

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    //  ~方法
    //  =========================================

    public Mediator getMediator() {
        return mediator;
    }
}
public class CDDriver extends Colleague {

    //  ~屬性
    //  =========================================

    /**光驅(qū)讀取出來的數(shù)據(jù)*/
    private String data = "";


    //  ~構(gòu)造器
    //  =========================================

    public CDDriver(Mediator mediator) {
        super(mediator);
    }

    //  ~方法
    //  =========================================
    /**讀取光盤*/
    public void readCD() {
        this.data = "設(shè)計(jì)模式,值得好好研究";
        this.getMediator().changed(this);
    }


    //  ~getter
    //  =========================================

    public String getData() {
        return this.data;
    }
}
public class CPU extends Colleague {

    //  ~屬性
    //  =========================================

    /**分解出來的視頻數(shù)據(jù)*/
    private String vedioData;
    /**分解出來的聲音數(shù)據(jù)*/
    private String soundData;


    //  ~構(gòu)造器
    //  =========================================

    public CPU(Mediator mediator) {
        super(mediator);
    }

    //  ~方法
    //  =========================================
    /**
     * 處理數(shù)據(jù),把數(shù)據(jù)分成音頻和視頻的數(shù)據(jù)
     * @param data
     */
    public void executeData(String data) {
        String[] ss = data.split(",");
        this.vedioData = ss[0];
        this.soundData = ss[1];
        getMediator().changed(this);
    }


    //  ~getter
    //  =========================================

    public String getVedioData() {
        return vedioData;
    }

    public String getSoundData() {
        return soundData;
    }

}
public class VideoCard extends Colleague {

    //  ~構(gòu)造器
    //  =========================================

    public VideoCard(Mediator mediator) {
        super(mediator);
    }

    //  ~方法
    //  =========================================

    public void showData(String data) {
        System.out.println("您正在觀看的是:"+data);
    }
}
public class SoundCard extends Colleague {

    //  ~構(gòu)造器
    //  =========================================

    public SoundCard(Mediator mediator) {
        super(mediator);
    }


    //  ~方法
    //  =========================================

    public void soundData(String data) {
        System.out.println("畫外音"+data);
    }
}
/**
 * 中介者,定義各個(gè)同事對(duì)象通信的接口
 */
public interface Mediator {

    /**
     * 同時(shí)對(duì)象在自身改變的時(shí)候來通知中介者方法
     * 讓中介者負(fù)責(zé)相應(yīng)的與其他同事對(duì)象的交互
     * @param colleague 同事對(duì)象自身。好讓中介者對(duì)象通過對(duì)象實(shí)例去獲取同事對(duì)象的狀態(tài)。
     */
    void changed(Colleague colleague);
}
public class MotherBoard implements Mediator {

    //  ~屬性
    //  =========================================

    /**
     * 需要知道要交互的同事類-光驅(qū)類
     */
    private CDDriver cdDriver = null;

    /**
     * 需要知道要交互的同事類-CPU類
     */
    private CPU cpu = null;

    /**
     * 需要知道要交互的同事類-顯卡類
     */
    private VideoCard videoCard = null;

    /**
     * 需要知道要交互的同事類-聲卡類
     */
    private SoundCard soundCard = null;


    //  ~方法
    //  =========================================

    @Override
    public void changed(Colleague colleague) {
        if (colleague == cdDriver) {
            //表示光驅(qū)讀數(shù)據(jù)了
            this.opeCDDriverReadData((CDDriver)colleague);
        } else if (colleague == cpu) {
            //表示CPU處理完了
            this.opeCpu((CPU)colleague);
        }
    }

    private void opeCDDriverReadData(CDDriver cd) {
        //調(diào)用方式時(shí),光驅(qū)讀完數(shù)據(jù),在這里獲取
        String data = cd.getData();
        //然后將數(shù)據(jù)傳給CPU,讓CPU來處理
        this.cpu.executeData(data);
    }

    private void opeCpu(CPU cpu) {
        //調(diào)用方式時(shí),cpu處理完數(shù)據(jù)了,在這里獲取
        String videoData = cpu.getVedioData();
        String soundData = cpu.getSoundData();
        //然后傳給聲卡和顯卡來顯示
        this.videoCard.showData(videoData);
        this.soundCard.soundData(soundData);
    }


    //  ~setter
    //  =========================================

    public MotherBoard setCdDriver(CDDriver cdDriver) {
        this.cdDriver = cdDriver;
        return this;
    }

    public MotherBoard setCpu(CPU cpu) {
        this.cpu = cpu;
        return this;
    }

    public MotherBoard setVideoCard(VideoCard videoCard) {
        this.videoCard = videoCard;
        return this;
    }

    public MotherBoard setSoundCard(SoundCard soundCard) {
        this.soundCard = soundCard;
        return this;
    }
}
public class TestClient {
    public static void main(String[] args) {
        // 創(chuàng)建中介者 --- 主板對(duì)象
        MotherBoard mediator = new MotherBoard();

        // 創(chuàng)建同事類
        CDDriver cdDriver = new CDDriver(mediator);
        CPU cpu = new CPU(mediator);
        VideoCard videoCard = new VideoCard(mediator);
        SoundCard soundCard = new SoundCard(mediator);

        // 讓中介者知道所有的同事
        mediator.setCdDriver(cdDriver)
                .setCpu(cpu)
                .setVideoCard(videoCard)
                .setSoundCard(soundCard);

        // 開始看電影放入光驅(qū)
        cdDriver.readCD();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容