设计模式之调停者(中介者)模式(三)

面向对象开发要求尽可能恰当地分配职责,要求对象能够独立地完成自己的任务。例如观察者模式,就是通过最小化对象与对象之间的职责交互,从而支持职责的合理分配。单利模式是将职责集中在某个对象中以便其他对象的访问与重用。与单例模式相似,调停者模式也是集中职责,但它是针对一组特殊的对象,而不是系统中全部的对象。

调停者模式也叫中介者模式,它的意图是定义一个对象,封装一组对象的交互,从而降低对象间的耦合度,避免了对象间的显式引用,并且可以独立地改变对象的行为。

以下例子统称中介者为例。

调停者模式的结构

调停者模式包含以下主要角色。

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

其结构图如图所示:
中介者模式的结构图

调停者模式的实现

抽象中介者

1
2
3
4
5
abstract class Mediator
{
public abstract void register(Colleague colleague);
public abstract void relay(Colleague cl); //转发
}

具体中介者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ConcreteMediator extends Mediator
{
private List<Colleague> colleagues=new ArrayList<Colleague>();
public void register(Colleague colleague)
{
if(!colleagues.contains(colleague))
{
colleagues.add(colleague);
colleague.setMedium(this);
}
}
public void relay(Colleague cl)
{
for(Colleague ob:colleagues)
{
if(!ob.equals(cl))
{
((Colleague)ob).receive();
}
}
}
}

抽象同事类

1
2
3
4
5
6
7
8
9
10
abstract class Colleague
{
protected Mediator mediator;
public void setMedium(Mediator mediator)
{
this.mediator=mediator;
}
public abstract void receive();
public abstract void send();
}

具体同事类

1
2
3
4
5
6
7
8
9
10
11
12
class ConcreteColleague1 extends Colleague
{
public void receive()
{
System.out.println("具体同事类1收到请求。");
}
public void send()
{
System.out.println("具体同事类1发出请求。");
mediator.relay(this); //请中介者转发
}
}

具体同事类

1
2
3
4
5
6
7
8
9
10
11
12
class ConcreteColleague2 extends Colleague
{
public void receive()
{
System.out.println("具体同事类2收到请求。");
}
public void send()
{
System.out.println("具体同事类2发出请求。");
mediator.relay(this); //请中介者转发
}
}

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MediatorPattern
{
public static void main(String[] args)
{
Mediator md=new ConcreteMediator();
Colleague c1,c2;
c1=new ConcreteColleague1();
c2=new ConcreteColleague2();
md.register(c1);
md.register(c2);
c1.send();
System.out.println("-------------");
c2.send();
}
}

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

常见案例及应用场景

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

应用场景:

  • 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

总结

调停者模式提供了松耦合的对象关系,避免了关联对象的显式引用。
该模式的优点:

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

该模式的缺点:

  • 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
Powered By Valine
v1.5.2