设计模式12-中介者模式

概念


定义

中介者模式,就是用一个中介对象来封装一系列的对象交互。中介者使得相关对象之间复杂的沟通和控制得到缓解,不需要显式的相互引用,从而使他们耦合松散。核心:封装对象间的交互

结构

中介者模式有两个角色,“同事类”和“中介者”。
同事类是平行关系,一般是实现自己的业务,当需要与其他同事进行通信的时候,就通知该同事持有的中介者,中介者再负责交互,所以每个同事类都应该知道中介者
中介者负责同事之间的交互,协调他们之间的关系,所以中介者需要知道他负责交互的同事对象。
这里写图片描述

关键说明

事实上上面已经讲述了中介者和同事类的关系。那么重点就在于,中介者怎么跟同事类交互,同事类又怎么在自身需要和其他同事类交互的时候,能够通知中介者。

其实也相当简单,只需要在同事类需要交互的时候,调用同事类的父类接口,找到中介者,将自身传给中介者的某个方法。由中介者来控制逻辑,协调交互就行了。
中介者也只需要在这个方法内判断,该同事类是想跟哪个同事类交互。因为中介者知道他旗下所有的同事类,所以只需要调用A同事类想要交互的B同事类方法即可

所以核心就是中介者的这个通知接口,只要设计好,定义好,其他同事类来调用这个方法接口即可

小实例


中介者接口

/**
 * 中介者,定义各个同事对象通信的接口
 */
public interface Mediator {
    /**
     * 同事对象在自身改变的时候来通知中介者的方法,
     * 让中介者去负责相应的与其他同事对象的交互
     * @param colleague 同事对象自身,好让中介者对象通过对象实例
     *                  去获取同事对象的状态
     */
    public void changed(Colleague colleague);
}

同事类接口

/**
 * 同事类的抽象父类
 */
public abstract class Colleague {
    /**
     * 持有中介者对象,每一个同事类都知道它的中介者对象
     */
    private Mediator mediator;
    /**
     * 构造方法,传入中介者对象
     * @param mediator 中介者对象
     */
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
    /**
     * 获取当前同事类对应的中介者对象
     * @return 对应的中介者对象
     */
    public Mediator getMediator() {
        return mediator;
    }
}

实体中介者类

/**
 * 具体的中介者实现
 */
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) {
        //某个同事类发生了变化,通常需要与其他同事交互
        if(colleague==colleagueA){
            colleagueB.someOperation();
        }
        //具体协调相应的同事对象来实现协作行为
    }

}

同事类实体

/**
 * 具体的同事类A
 */
public class ConcreteColleagueA extends Colleague {
    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }
    /**
     * 示意方法,执行某些业务功能
     */
    public void someOperation() {
        //在需要跟其他同事通信的时候,通知中介者对象
        System.out.println("我是A,想和B通信");
        getMediator().changed(this);
    }
}
/**
 * 具体的同事类B
 */
public class ConcreteColleagueB extends Colleague {
    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }
    /**
     * 示意方法,执行某些业务功能
     */
    public void someOperation() {
        //在需要跟其他同事通信的时候,通知中介者对象
        System.out.println("我是B");
        getMediator().changed(this);
    }
}

测试类

public class Client {

    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();
        ConcreteColleagueA a = new ConcreteColleagueA(mediator);
        ConcreteColleagueB b = new ConcreteColleagueB(mediator);
        mediator.setConcreteColleagueA(a);
        mediator.setConcreteColleagueB(b);
        a.someOperation();
    }
}

其重点就是中介者的changed()接口,所有的同事需要交互的时候,都会调用它自身的中介者的这个接口。
中介者在这个接口对调用的同事进行判断,分析他们想要和谁交互

具体实例


这是一个主板和主板上各个组件进行数据交互的实例。
组件有光驱,CPU,声卡,显卡四个组件。他们之间不进行直接交互,而是通过主板这个中介进行数据通信交互。
从光驱读取数据,传给中介者。中介者得到数据后,传给CPU。CPU分析数据,得出声音数据和影像数据。然后通知中介者。中介者得到了声音数据和影像数据,再分别通知声卡和显卡工作,最后完成了整个体系的交互

中介者接口

/**
 * 中介者对象的接口
 */
public interface Mediator {
    /**
     * 同事对象在自身改变的时候来通知中介者的方法,
     * 让中介者去负责相应的与其他同事对象的交互
     * @param colleague 同事对象自身,好让中介者对象通过对象实例
     *                  去获取同事对象的状态
     */
    public void changed(Colleague colleague);
}

同事类父类

/**
 * 同事类的抽象父类
 */
public abstract class Colleague {
    /**
     * 持有中介者对象,每一个同事类都知道它的中介者对象
     */
    private Mediator mediator;
    /**
     * 构造方法,传入中介者对象
     * @param mediator 中介者对象
     */
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
    /**
     * 获取当前同事类对应的中介者对象
     * @return 对应的中介者对象
     */
    public Mediator getMediator() {
        return mediator;
    }
}

同事类实例

/**
 * 光驱类,一个同事类
 */
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);
    }
}
/**
 * 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);
    }

}
/**
 * 声卡类,一个同事类
 */
public class SoundCard extends Colleague{
    public SoundCard(Mediator mediator) {
        super(mediator);
    }

    /**
     * 按照声频数据发出声音
     * @param data 发出声音的数据
     */
    public void soundData(String data){
        System.out.println("画外音:"+data);
    }

}
/**
 * 显卡类,一个同事类
 */
public class VideoCard extends Colleague{
    public VideoCard(Mediator mediator) {
        super(mediator);
    }

    /**
     * 显示视频数据
     * @param data 被显示的数据
     */
    public void showData(String data){
        System.out.println("您正观看的是:"+data);
    }   
}

中介者实体类

/**
 * 主板类,实现中介者接口
 */
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);
    }

}

测试类

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();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32020035/article/details/80904451