中介者模式

设计模式文章

中介者模式

代理模式

抽象工厂模式详解 —— head first 设计模式

装饰者模式

适配器模式

策略模式

观察者模式

建造者模式 (Builder)

概述

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

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

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

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

模式的定义与特点

中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介者模式是一种对象行为型模式,其主要优点如下。

  1. 降低了对象之间的耦合性,使得对象易于独立地被复用。

  2. 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

其主要缺点是:当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护

模式的结构与实现

中介者模式实现的关键是找出“中介者”,下面对它的结构和实现进行分析。

1. 模式的结构

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

  1. 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。

  2. 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

  3. 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  4. 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。


中介者模式的结构图如图 1 所示。

中介者模式的结构图

 

2. 模式的实现

中介者模式的实现代码如下:

package mediator;
import java.util.*;
public class MediatorPattern {
    static void main(String[] args) {
        Mediator md=new ConcreteMediator();
        Colleague c1,c2;
        c1= ConcreteColleague1();
        c2= ConcreteColleague2();
        md.register(c1);
        md.register(c2);
        c1.send();
        System.out.println("-------------");
        c2.send();
    }
}
//抽象中介者
abstract  Mediator {
     register(Colleague colleague);
    void relay(Colleague cl); 转发
}
具体中介者
class ConcreteMediator extendsprivate List<Colleague> colleagues=new ArrayList<Colleague>();
     register(Colleague colleague) {
        if(!colleagues.contains(colleague)) {
            colleagues.add(colleague);
            colleague.setMedium(this);
        }
    }
     relay(Colleague cl) {
        for(Colleague ob:colleagues) {
            ob.equals(cl)) {
                ((Colleague)ob).receive();
            }   
        }
    }
}
抽象同事类
 Colleague {
    protected Mediator mediator;
     setMedium(Mediator mediator) {
        this.mediator=mediator;
    }   
     receive();   
     send();
}
具体同事类
class ConcreteColleague1  receive(){
        System.out.println("具体同事类1收到请求。");
    }   
     send() {
        System.out.println("具体同事类1发出请求。");
        mediator.relay(this); 请中介者转发
    }
}
class ConcreteColleague2  receive(){
        System.out.println("具体同事类2收到请求。" send(){
        System.out.println("具体同事类2发出请求。"    }
}

 程序的运行结果如下:

具体同事类1发出请求。
具体同事类2收到请求。
-------------
具体同事类2发出请求。
具体同事类1收到请求。

模式的应用场景

前面分析了中介者模式的结构与特点,下面分析其以下应用场景。

  • 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。

  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

模式的扩展

在实际开发中,通常采用以下两种方法来简化中介者模式,使开发变得更简单。

  1. 不定义中介者接口,把具体中介者对象实现成为单例

  2. 同事对象不持有中介者,而是在需要的时f矣直接获取中介者对象并调用。

下图是简化中介者模式的结构图。

简化中介者模式的结构图



程序代码如下:
 SimpleMediatorPattern {
     main(String[] args) {
        SimpleColleague c1,1)"> SimpleConcreteColleague1();
        c2= SimpleConcreteColleague2();
        c1.send();
        System.out.println("-----------------");
        c2.send();
    }
}
简单单例中介者 SimpleMediator {
   // 确保只初始化一次
private static SimpleMediator smd= SimpleMediator(); private List<SimpleColleague> colleagues=new ArrayList<SimpleColleague>(); private SimpleMediator(){}
  // 做成单例
static SimpleMediator getMedium(){
    
return(smd);
  }
register(SimpleColleague colleague) { colleagues.contains(colleague)){ colleagues.add(colleague); } }
relay(SimpleColleague scl) { (SimpleColleague ob:colleagues) { ob.equals(scl)) { ((SimpleColleague)ob).receive(); } } } }
interface SimpleColleague { send(); }
class SimpleConcreteColleague1 implements SimpleColleague { SimpleConcreteColleague1(){ SimpleMediator smd=SimpleMediator.getMedium(); smd.register(); } receive() {
    System.out.println(
"具体同事类1:收到请求。");
  }
send() { SimpleMediator smd=SimpleMediator.getMedium(); System.out.println("具体同事类1:发出请求..."); smd.relay( } }
class SimpleConcreteColleague2 SimpleColleague { SimpleConcreteColleague2(){ SimpleMediator smd=); }
receive() {
    System.out.println(
"具体同事类2:收到请求。");
  }
SimpleMediator.getMedium(); System.out.println("具体同事类2:发出请求..." } }

 程序运行结果如下:

具体同事类1:发出请求...
具体同事类2:收到请求。
-----------------
具体同事类2:发出请求...
具体同事类1:收到请求。

 

观察者模式和中介者模式的异同

1. 基本定义区别

  • 观察者模式:属于行为型模式,指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式。中介者模式:

  • 中介者模式:属于行为型模式;定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

相同点:

  • 都属于行为型模式

  • 都为了处理一对多的关系

2. URML图区别:

观察者模式:

中介者模式:

相同点:
  • 处理业务逻辑的对象都被抽象化(ConcreteColleague和ConcreteObserver都符合单一职责)

  • 中介者和观察者都有统一管理的list集合。

  • 都有循环通知的方法

3. 使用场景

  • 观察者模式:只能从从一的一方循环的通知,属于单向。(好比上课,只能老实授课给班上所有的学生,反过来不行)

  • 中介者模式:可以从任一方循环通知,属于双向。(好比分享会,每个人都可以分享自己的事情给别人)

参考文章

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结