对于那些存在对象之间复杂交互关系的系统,中介者模式提供了一种简化复杂交互的解决方案,他通过引入一个中介者,将原本对象之间的两两交互转化为每个对象与中介者之间的交互,中介者可以对对象之间的通信进行控制与协调,极大地降低了原有系统的耦合度,使得系统更加灵活,也更易于扩展。
模式定义:
中介者模式(mediator pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互,中介者模式又称为调停者模式,他是一个对象行为型模式。
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
participants
The classes and/or objects participating in this pattern are:
- Mediator (IChatroom)
- defines an interface for communicating with Colleague objects 定义了一个接口,用于与各同事对象之间通信
- ConcreteMediator (Chatroom)
- implements cooperative behavior by coordinating Colleague objects
- knows and maintains its colleagues
- Colleague classes (Participant)
- each Colleague class knows its Mediator object
- each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague
抽象同事类:定义各同事的公有方法。
具体同事类:每一个同事对象都引用一个中介者对象;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中定义的方法。
模式分析:
中介者模式使得对象之间的关系数量急剧减少,将系统的网状结构变为了以中介者为中心的星状结构。
如果对象之间存在多对多的相互关系,可以将对象之间的一些交互行为从各个对象中分离出来,并集中封装在一个中介者对象中,并由该中介者进行通信和协调,这样对象之间多对多的复杂关系就可以通过相对简单的多对一关系实现。通过引入中介者类简化对象之间的复杂交互,符合迪米特法则,简化了系统的理解和实现。
在这里中介者承担了以下两方面的职责:
1.中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显示引用其他同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用属于中介者在结构上的支持。
2.协调作用(行为性):中介者可以更进一步对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。
public abstract class Mediator { protected ArrayList colleagues; public void register(Colleague colleague) { colleagues.add(colleague); } public abstract void operation(); }
在具体中介者类将实现抽象类的抽象方法:
public class ConcreteMediator extends Mediator { public void operation() { ...... ((Colleague)(colleagues.get(0))).method1(); ...... } }
在具体中介者类中将调用同事类的方法,调用时可以增加一些自己的业务代码对调用进行控制。
在抽象同事类中维持了一个抽象中介者的引用,用于调用中介者的方法,典型代码如下:
public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator=mediator; } public abstract void method1(); public abstract void method2(); }
具体同事类:
public class ConcreteColleague extends Colleague { public ConcreteColleague(Mediator mediator) { super(mediator); } public void method1() { ...... } public void method2() { mediator.operation1(); } }
在具体同事类中实现了在抽象同事类中声明的方法,其他方法method1()是同事类的自身方法(self-method),用于处理自己的行为,而方法method2()是依赖方法(depend-method),用于调用中介者中定义的方法,依赖中介者来完成相应的行为,例如调用另一个同事类的相关方法。
实例:
抽象中介者类:
public abstract class AbstractChatroom { public abstract void register(Member member); public abstract void sendText(String from,String to,String message); public abstract void sendImage(String from,String to,String image); }
抽象同事类:
public abstract class Member { protected AbstractChatroom chatroom; protected String name; public Member(String name) { this.name=name; } public String getName() { return name; } public void setName(String name) { this.name=name; } public AbstractChatroom getChatroom() { return chatroom; } public void setChatroom(AbstractChatroom chatroom) { this.chatroom=chatroom; } public abstract void sendText(String to,String message); public abstract void sendImage(String to,String image); public void receiveText(String from,String message) { System.out.println(from+"发送文本给 "+this.name+",内容为:"+message); } public void receiveImage(String from,String image) { System.out.println(from+"发送图片给 "+this.name+",内容为:"+image); } }
由于不同类型的会员发送文本信息和图片信息的方式有所区别,因此在member类中还对这2个方法进行了抽象声明。
具体中介者.
public class ChatGroup extends AbstractChatroom { public Hashtable members=new Hashtable(); @Override public void register(Member member) { if(!members.contains(member)) { members.put(member.getName(), member); member.setChatroom(this); } } @Override public void sendText(String from, String to, String message) { Member member=(Member)members.get(to); String newMessage=message; newMessage=message.replaceAll("日", "*"); member.receiveText(from, newMessage); } @Override public void sendImage(String from, String to, String image) { Member member=(Member)members.get(to); //模拟图片大小判断 if(image.length()>5) { System.out.println("图片太大,发送失败"); } else { member.receiveImage(from, image); } } }
具体同事类:
public class CommonMember extends Member { public CommonMember(String name) { super(name); } @Override public void sendText(String to, String message) { System.out.println("普通会员发送信息"); chatroom.sendText(name, to, message); } public void sendImage(String to,String image){ System.out.println("普通会员不能发送图片"); } }
public class DiamondMember extends Member{ public DiamondMember(String name) { super(name); } @Override public void sendText(String to, String message) { System.out.println("钻石会员发送信息"); chatroom.sendText(name, to, message); } public void sendImage(String to,String image){ System.out.println("钻石会员发送图片"); chatroom.sendImage(name, to, image); } }
会员发送信息时,先发送给中介者,由中介者类对信息进行统一的处理,然后在转发给接收者,在这里,中介者充当了信息发送者和接收者之间的第3者,他在对信息进行过滤进行判断后再对信息进行转发。
可以很方便引入新的具体中介者类和同事类。