zoukankan      html  css  js  c++  java
  • 设计模式-19中介者模式(Mediator Pattern)

    1.模式动机

    在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。例如,每个人必须记住他(她)所有朋友的电话;而且,朋友中如果有人的电话修改了,他(她)必须告诉其他所有的朋友修改,这叫作“牵一发而动全身”,非常复杂。

    如果把这种“网状结构”改为“星形结构”的话,将大大降低它们之间的“耦合性”,这时只要找一个“中介者”就可以了。如前面所说的“每个人必须记住所有朋友电话”的问题,只要在网上建立一个每个朋友都可以访问的“通信录”就解决了。这样的例子还有很多,例如,你刚刚参力口工作想租房,可以找“房屋中介”;或者,自己刚刚到一个陌生城市找工作,可以找“人才交流中心”帮忙。

    在软件的开发过程中,这样的例子也很多,例如,在 MVC 框架中,控制器(C)就是模型(M)和视图(V)的中介者;还有大家常用的 QQ 聊天程序的“中介者”是 QQ 服务器。所有这些,都可以采用“中介者模式”来实现,它将大大降低对象之间的耦合性,提高系统的灵活性。

    2.模式定义

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

    中介者模式又称为调停者模式,它是一种对象行为型模式

    3.模式结构

    中介者模式包含以下主要角色:

    • 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
    • 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
    • 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
    • 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

    4.模式代码

    # 抽象中介者
    public abstract class Mediator {
        public abstract void register(Colleague colleague);
        public abstract void relay(Colleague colleague);
    }
    
    # 具体中介者
    public class ConcreteMediator extends Mediator {
    
        private List<Colleague> list = new ArrayList<>();
    
        @Override
        public void register(Colleague colleague) {
            if (!list.contains(colleague)) {
                list.add(colleague);
                colleague.setMediator(this);
            }
        }
    
        @Override
        public void relay(Colleague colleague) {
            for (Colleague c : list) {
                if (!c.equals(colleague)) {
                    c.receive();
                }
            }
        }
    }
    
    # 抽象同事类
    public abstract class Colleague {
        protected Mediator mediator;
    
        public void setMediator(Mediator mediator) {
            this.mediator = mediator;
        }
    
        public abstract void receive();
        public abstract void send();
    }
    
    # 具体同事类 A 和 B
    public class ConcreteColleagueA extends Colleague {
        @Override
        public void receive() {
            System.out.println("具体同事类 A 收到请求");
        }
    
        @Override
        public void send() {
            System.out.println("具体同事类 A 发出请求");
            mediator.relay(this);
        }
    }
    public class ConcreteColleagueB extends Colleague {
        @Override
        public void receive() {
            System.out.println("具体同事类 B 收到请求");
        }
    
        @Override
        public void send() {
            System.out.println("具体同事类 B 发出请求");
            mediator.relay(this);
        }
    }
    
    # Client
    public class Client {
        public static void main(String[] args) {
            Mediator m = new ConcreteMediator();
            Colleague cA = new ConcreteColleagueA();
            Colleague cB = new ConcreteColleagueB();
    
            m.register(cA);
            m.register(cB);
    
            cA.send();
            System.out.println("-----分割线");
            cB.send();
        }
    }
    

    5.总结

    分析

    • 中介者模式可以使对象之间的关系数量急剧减少
    • 中介者承担两方面的职责
      • 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用属于中介者在结构上的支持。
      • 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。

    优点

    • 低了对象之间的耦合性,使得对象易于独立地被复用
    • 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展

    缺点

    • 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护
  • 相关阅读:
    文件上传---普通文件fileupload.jar和url文件httpUrlConnection
    HttpClient学习整理
    编写更少量的代码:使用apache commons工具类库
    多线程进阶
    多线程下HashMap的死循环问题
    线程本地变量ThreadLocal源码解读
    Eclipse工作常见问题总结
    Java集合---ConcurrentHashMap原理分析
    Java集合---Arrays类源码解析
    Java集合---LinkedList源码解析
  • 原文地址:https://www.cnblogs.com/wuqinglong/p/12607521.html
Copyright © 2011-2022 走看看