18.中介者模式

1.什么是中介者模式?

中介者模式:定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显式地相互引用,从而使其耦合松散,而且用户可以独立的改变他们之间的交互。

说人话就是:降低原有对象之间的复杂引用关系

举个例子:QQ给10个人发同样文件,需要加10次好友,发10次。拉个群,发一次就行。这个群相当于就是中介者。

 

2.中介者模式结构

(1)Mediator(抽象中介者):它定义了一个接口,该接口用于与各同事对象之间进行通信

(2)ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用

(3)Colleague(抽象同事类):它定义各个同事类共有的方法,并声明了一些抽象方法供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用与中介者通信

(4)ConcreteColleague(具体同事类):他是抽象同事类的子类,每一个同事对象在需要和其他同事对象通信时先与中介者通信,通过中介者间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。

 

3.中介者模式实现

(1)抽象中介者类

/**
 * 抽象中介者类
 */
public abstract class Mediator {
    protected ArrayList colleagues = new ArrayList();//用于存储同事对象

    //注册方法,用于增加同事对象
    public void register(Colleague colleague){
        colleagues.add(colleague);
    }

    //声明抽象的业务方法
    public abstract void operation();
}

(2)具体中介者类代码

/**
 * 具体中介者类代码
 */
public class ConcreteMediator extends Mediator {
    //实现业务方法,封装同事之间的调用
    @Override
    public void operation() {
        //...
        ((Colleague)(colleagues.get(0))).method1();//通过中介者调用同事类的方法
        //...
    }
}

(3)抽象同事类

/**
 * 抽象同事类
 */
public abstract class Colleague {
    protected Mediator mediator;//维持一个抽象中介者的引用

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

    public abstract void method1();//声明自身方法,处理自己的行为

    //定义依赖方法,与中介者进行通信
    public void method2(){
        mediator.operation();
    }

}

(4)具体同事类

/**
 * 具体同事类
 */
public class ConcreteColleague extends Colleague {

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

    //实现自身方法
    @Override
    public void method1() {

    }
}

 

4.中介者模式实例——增删用户,用户列表以及用户信息跟着进行增删

(1)抽象中介者类

/**
 * 抽象中介者类
 */
public abstract class Mediator {
    public abstract void componentChanged(Component c);
}

(2)具体中介者类

/**
 * 具体中介者类
 */
public class ConcreteMediator extends Mediator {
    //维持对各个同事对象的引用
    public Button addButton;
    public List list;
    public TextBox userNameTextBox;
    public ComboBox cb;

    @Override
    public void componentChanged(Component c) {
        //单机按钮
        if(c == addButton){
            System.out.println("--单机增加按钮--");
            list.update();
            cb.update();
            userNameTextBox.update();
        }else if(c == list){//从列表框选择客户
            System.out.println("--从列表框选择客户--");
            cb.select();
            userNameTextBox.setText();
        }else if(c == cb){//从组合框选择客户
            System.out.println("--从组合框选择客户--");
            cb.select();
            userNameTextBox.setText();
        }

    }
}

(3)抽象组件类,充当抽象同事类

/**
 * 抽象组件类,充当抽象同事类
 */
public abstract class Component {
    protected Mediator mediator;

    public void setMediator(Mediator mediator){
        this.mediator = mediator;
    }

    //转发调用
    public void changed(){
        mediator.componentChanged(this);
    }

    public abstract void update();
}

(4)按钮类,充当具体同事类

/**
 * 按钮类,充当具体同事类
 */
public class Button extends Component {
    @Override
    public void update() {
        //按钮不产生相应
    }
}

(5)列表框类,充当具体同事类

/**
 * 列表框类,充当具体同事类
 */
public class List extends Component {
    @Override
    public void update() {
        System.out.println("列表框增加一条:张无忌");
    }

    public void select(){
        System.out.println("列表框选中项:小龙女");
    }
}

(6)组合框类,充当具体同事类

/**
 * 组合框类,充当具体同事类
 */
public class ComboBox extends Component {

    @Override
    public void update() {
        System.out.println("组合框增加一项:张无忌");
    }

    public void select(){
        System.out.println("列表框选中项:小龙女");
    }
}

(7)文本框类,充当具体同事类

/**
 * 文本框类,充当具体同事类
 */
public class TextBox extends Component {
    @Override
    public void update() {
        System.out.println("客户信息增加成功后文本框清空");
    }

    public void setText(){
        System.out.println("文本框显示:小龙女");
    }
}

(8)客户端类

public class Client {
    public static void main(String[] args) {
        //定义中介者对象
        ConcreteMediator mediator;
        mediator = new ConcreteMediator();

        //定义同事对象
        Button addBT = new Button();
        List list = new List();
        ComboBox cb = new ComboBox();
        TextBox userNameTb = new TextBox();

        addBT.setMediator(mediator);
        list.setMediator(mediator);
        cb.setMediator(mediator);
        userNameTb.setMediator(mediator);

        mediator.addButton = addBT;
        mediator.list = list;
        mediator.cb = cb;
        mediator.userNameTextBox = userNameTb;

        addBT.changed();
        System.out.println("--------");
        list.changed();

    }
}

(9)输出结果及路径

18.中介者模式_第1张图片

 

5.扩展中介者与同事类

上述实例如果需要新增一个Label,无需修改ConcreteMediator,而是增加一个子类,然后覆盖componentChanged()方法。原来组件类代码无需变动,客户端代码需要少许修改。

(1)新增同事类

public class Label extends Component {
    @Override
    public void update() {
        System.out.println("文本标签内容梗概,客户信息总数加1");
    }
}

(2)具体中介者抽出子类

public class SubConcreteMediator extends ConcreteMediator {
    //增加对Label的引用
    public Label label;

    public void componentChanged(Component c) {
        //单机按钮
        if(c == addButton){
            System.out.println("--单机增加按钮--");
            list.update();
            cb.update();
            userNameTextBox.update();
            //文本标签更新
            label.update();
        }else if(c == list){//从列表框选择客户
            System.out.println("--从列表框选择客户--");
            cb.select();
            userNameTextBox.setText();
        }else if(c == cb){//从组合框选择客户
            System.out.println("--从组合框选择客户--");
            cb.select();
            userNameTextBox.setText();
        }

    }
}

(3)修改客户端

public class Client {
    public static void main(String[] args) {
//        //定义中介者对象
//        ConcreteMediator mediator;
//        mediator = new ConcreteMediator();

        //用新增具体中介者定义中介者对象、
        SubConcreteMediator mediator;
        mediator = new SubConcreteMediator();

        //定义同事对象
        Button addBT = new Button();
        List list = new List();
        ComboBox cb = new ComboBox();
        TextBox userNameTb = new TextBox();
        Label label = new Label();

        addBT.setMediator(mediator);
        list.setMediator(mediator);
        cb.setMediator(mediator);
        userNameTb.setMediator(mediator);
        label.setMediator(mediator);

        mediator.addButton = addBT;
        mediator.list = list;
        mediator.cb = cb;
        mediator.userNameTextBox = userNameTb;
        mediator.label = label;

        addBT.changed();
        System.out.println("--------");
        list.changed();

    }
}

 

6.中介者模式的优缺点

优:

(1)简化了对象之间的交互

(2)将各同事对象解耦

(3)减少子类生成

缺:

系统复杂

 

7.中介者模式适用环境

(1)系统中对象之间存在复杂引用关系

(2)一个对象由于引用了其他很多对象,并且直接和这些对象通信。导致该对象难以复用

(3)想通过一个中间类来封装多个类中的行为,而又不想有太多的子类

你可能感兴趣的:(设计模式,设计模式)