zoukankan      html  css  js  c++  java
  • Java设计模式----中介者模式

    说到中介大家都不会陌生,买房子租房子有中介,出国留学有中介,买卖二手车还是有中介。那么中介到底是个什么角色呢?实际上,中介就是让买卖双方不必面对面直接交流,由他/她来完成买卖双方的交易,达到解耦买卖人,同时给买卖双方带来方便的一个职业角色。对于应用开发来说,代码就是来源于生活,就是生活的抽象,因此,中介这种模式也应用在应用开发中,这就是我下面要介绍的----中介者模式。


    1.中介者模式

    中介者模式(Mediator Pattern) 定义了一个对象, 这个对象封装了其它对象之间的交互行为。

    这个定义的对象通常我门称为Mediator, 它是一个“中介”, 封装的是其它对象之间的交互这种行为,所以,中介者模式是一种行为模式中介者模式的引入,多个对象由原来的互相直接交互,变成了通过Mediator进行交互,这样,交互对象之间就不必相互依赖或者关联,于是就松散了它们之间的耦合关系。中介者模式的结构图如下:

    从类图中可以看到,中介与交互对象Colleague关联, 而交互对象之间没有关联,这就是说,随着交互对象的增长,Mediator所要关联的对象也会越来越多,实际上就是把关联转移到了Mediator, Mediator本身的逻辑也会越来越复杂。再从时序图上看一下交互发生时的整个过程:

     可以清楚的看到Colleague1和Colleague2之间的交互过程,都是通过Mediator进行的。简单地概括起来,中介者模式提供的解决方案就是:

    • 定义一个Mediator对象来封装对象的交互
    • 对象通过Mediator作为代理,与其它对象进行交互

    3.代码实现

    典型的中介者模式应用的场景,就是将其应用在GUI应用上各种按钮、控件之间的通信,比如这里设计一个简化的场景,有三个按钮:按钮一(Btn1)、按钮二(Btn2)、按钮三(Btn3),当你点击按钮一时,按钮一置灰,此时点击按钮二,按钮二置灰。按钮一恢复,即Radio button,想想过去的老式收音机,一次按钮不能连续按两次。

    点击按钮即执行一次命令,即按按钮具有执行命令的行为,故而可以抽象出一个interface来定义这种执行命令的行为。每个实现它的按钮,被点击的时候,都应该执行action方法。

    interface Action {
       void action();
    }

    中介者interface Mediator, 定义了一系列的接口。btn1(),btn2(),btn3()供按钮btn1,btn2,btn3调用,registerBtn1(), registerBtn2(), registerBtn3()在Mediator中分别注册三个按钮。

    interface Mediator {
        void btn1();
        void btn2();
        void btn3();
    
        void registerBtn1(Btn1 b);
        void registerBtn2(Btn2 b);
        void registerBtn3(Btn3 b);
    }

    BtnMediator是Mediator的实现类,它关联了所有按钮(Btn1, Btn2, Btn3), 实现了接口的方法。

    class BtnMediator implements Mediator {
    
        Btn1 btn1;
        Btn2 btn2;
        Btn3 btn3;
    
        @Override
        public void btn1() {
            btn1.setEnabled(false);
            btn2.setEnabled(true);
            btn3.setEnabled(true);
        }
    
        @Override
        public void btn2() {
            btn1.setEnabled(true);
            btn2.setEnabled(false);
            btn3.setEnabled(true);
        }
    
        @Override
        public void btn3() {
            btn1.setEnabled(true);
            btn2.setEnabled(true);
            btn3.setEnabled(false);
        }
    
        @Override
        public void registerBtn1(Btn1 b) {
            btn1 = b;
        }
    
        @Override
        public void registerBtn2(Btn2 b) {
            btn2 = b;
        }
    
        @Override
        public void registerBtn3(Btn3 b) {
            btn3 = b;
        }
    }

    定义三个按钮,它们都继承了JButton, 并且实现了Action,这三个按钮就是交互对象。需要注意的就是按钮与Mediator相互关联,所以按钮的属性中定义了一个Mediator成员变量, 构造器中包含有初始化JButton对象的方法,比如super("btn1")定义按钮显示名称,addActionLIstener(al)是为按钮添加监听,因为Java中,按钮是事件驱动的。med.registerBtnx()即注册该按钮到Mediator中。

    class Btn1 extends JButton implements Action {
    
        Mediator med;
    
        public Btn1(ActionListener al, Mediator m) {
            super("btn1");
            addActionListener(al);
            this.med = m;
            med.registerBtn1(this);
        }
    
        @Override
        public void action() {
            med.btn1();
        }
    }
    
    class Btn2 extends JButton implements Action {
    
        Mediator med;
    
        public Btn2(ActionListener al, Mediator m) {
            super("btn2");
            addActionListener(al);
            med = m;
            med.registerBtn2(this);
        }
    
        @Override
        public void action() {
            med.btn2();
        }
    }
    
    class Btn3 extends JButton implements Action {
    
        Mediator med;
    
        public Btn3(ActionListener al, Mediator m) {
            super("btn3");
            addActionListener(al);
            med = m;
            med.registerBtn3(this);
        }
    
        @Override
        public void action() {
            med.btn3();
        }
    }

     最后定义了本例子的演示入口,MediatorDemo继承JFrame,这种写法也是Swing当中常见的写法。 定义了一个静态内部类MyListener 监听点击按钮事件。 在构造器中初始化此控件。运行main方法。

    public class MediatorDemo extends JFrame {
        Mediator med = new BtnMediator();
    
        public MediatorDemo() {
            ActionListener al = new MyListener();
            add(new Btn1(al, med));
            add(new Btn2(al, med));
            add(new Btn3(al, med));
            setSize(300,100);
            setLayout(new FlowLayout());
            setVisible(true);
        }
    
        static class MyListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                Action a = (Action) e.getSource();
                a.action();
            }
        }
    
    
        public static void main(String[] args) {
            new MediatorDemo();
        }
    }

    结果:

    稍等片刻,桌面弹出一个面板,面板上有三个按钮,点击btn1, 置灰; 再点击btn3, btn3置灰,btn1恢复。


    4.总结

    前面的章节中也反复提到过,中介者模式就是封装一系列对象的交互行为,并通过实现了一个Radio Button的例子演示了中介者模式的应用。GUI中,各种控件之间的通信,都可以通过Mediator来封装。在实际开发过程中,经常会出现对象之间交互的情况,那么这些场景是否适合应用中介者模式,就需要具体问题具体分析了,因为如果交互的对象增多,那么Mediator的方法也会不断增加,如果不同对象之间的交互上依赖于更多其它对象,那么Mediator也就会依赖很多其它对象。所以,想应用中介者模式,就需要把对象之间的通信行为定义的比较独立,比如按下btn1,btn1就置灰,btn2,btn3设置为true......而无需再依赖其它不确定的条件。

  • 相关阅读:
    爬虫开头
    JAVA练习笔记---copyfile
    String
    十进制转化为八进制--栈实现
    一、给计算机专业的同学,计算机鸡汤
    数值的整数次方
    剪绳子-动态规划-贪婪
    二进制中为1 的数字个数
    机器人运动范围——回溯法应用
    矩阵的路径
  • 原文地址:https://www.cnblogs.com/yxlaisj/p/10387796.html
Copyright © 2011-2022 走看看