中介者模式
定义
用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介模式(Mediator)又称调停者模式,它的目的是把多方会谈变成双方会谈,从而实现多方的松耦合。
解决
对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
优点
- 简化了对象之间的交互。
- 将各同事解耦。
- 减少子类生成。
- 可以简化各同事类的设计和实现。
缺点
- 在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
结构
中介者模式包含如下角色:
- Mediator: 抽象中介者
- ConcreteMediator: 具体中介者
- Colleague: 抽象同事类
- ConcreteColleague: 具体同事类
实现
package mediatorpattern;
/**
* 抽象中介类
*/
public abstract class Mediator {
//定义一个抽象的发送消息方法,得到同事对象和发送消息
public abstract void send(String msg , Colleague colleague);
}
class ConcreteMediator extends Mediator {
// 需要了解所有的具体同事对象
private ConcreteColleague1 c1;
private ConcreteColleague2 c2;
public ConcreteColleague1 getC1() {
return c1;
}
public void setC1(ConcreteColleague1 c1) {
this.c1 = c1;
}
public ConcreteColleague2 getC2() {
return c2;
}
public void setC2(ConcreteColleague2 c2) {
this.c2 = c2;
}
@Override
public void send(String message, Colleague colleague) {
// 重写发送信息的方法,根据对象做出选择判断,通知对象
if (colleague == c1) {
c2.notifyMsg(message);
} else {
c1.notifyMsg(message);
}
}
}
package mediatorpattern;
public abstract class Colleague {
protected Mediator mediator;
//构造方法,得到中介者对象
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void sendMsg(String message);
public abstract void notifyMsg(String message);
}
class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
@Override
public void sendMsg(String message) {
mediator.send(message, this);
}
@Override
public void notifyMsg(String message) {
System.out.println("同事1得到消息:" + message);
}
}
class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
@Override
public void sendMsg(String message) {
mediator.send(message, this);
}
@Override
public void notifyMsg(String message) {
System.out.println("同事2得到消息:" + message);
}
}
package mediatorpattern;
public class MediatorClient {
public static void main(String[] args) {
ConcreteMediator concreteMediator = new ConcreteMediator();
// 让两个具体同事类认识中介者对象
ConcreteColleague1 concreteColleague1 = new ConcreteColleague1(
concreteMediator);
ConcreteColleague2 concreteColleague2 = new ConcreteColleague2(
concreteMediator);
// 让中介者认识各个具体同事类对象
concreteMediator.setC1(concreteColleague1);
concreteMediator.setC2(concreteColleague2);
// 具体同事类对象的消息发送都是通过中介者对象转发
concreteColleague1.sendMsg("吃过饭了咩?");
concreteColleague2.sendMsg("没有捏,你要请客嘛?");
}
}
实例
美国和伊拉克冲突,安理会充当中介。
package mediatorpattern.demo;
//联合国机构 (Mediator)
public abstract class UnitedNations {
//声明
public abstract void declare(String msg,Country colleague);
}
//联合国安理会 (ConcreteMediator)
class UnitedNationsSecurityCouncil extends UnitedNations{
private USA colleague1;
private Iraq colleaque2;
//美国
public void setColeague1(USA coleague1) {
this.colleague1 = coleague1;
}
//伊拉克
public void setColleaque2(Iraq colleaque2) {
this.colleaque2 = colleaque2;
}
@Override
public void declare(String msg, Country colleague) {
if(colleague==colleague1)
{
colleaque2.getMsg(msg);
}
else
{
colleague1.getMsg(msg);
}
}
}
package mediatorpattern.demo;
//国家 (Colleague)
public class Country {
protected UnitedNations mediator;
public Country(UnitedNations mediator)
{
this.mediator=mediator;
}
}
//美国 (ConcreteColleague1)
class USA extends Country {
public USA(UnitedNations mediator) {
super(mediator);
}
//声明
public void declare(String msg)
{
mediator.declare(msg,this);
}
//获得消息
public void getMsg(String msg)
{
System.out.println("美国获得对方消息:"+msg);
}
}
//伊拉克 (ConcreteColleague2)
class Iraq extends Country {
public Iraq(UnitedNations mediator) {
super(mediator);
}
//声明
public void declare(String msg)
{
mediator.declare(msg,this);
}
//获得消息
public void getMsg(String msg)
{
System.out.println("伊拉克获得对方消息:"+msg);
}
}
package mediatorpattern.demo;
/**
* 美国伊拉克冲突, 安理会充当中介
*/
public class MediatorClient {
public static void main(String[] args) {
UnitedNationsSecurityCouncil unitedNationsSecurityCouncil=new UnitedNationsSecurityCouncil();
//国家认识一下安理会
USA c1=new USA(unitedNationsSecurityCouncil);
Iraq c2=new Iraq(unitedNationsSecurityCouncil);
//安理会认识一下国家
unitedNationsSecurityCouncil.setColeague1(c1);
unitedNationsSecurityCouncil.setColleaque2(c2);
c1.declare("不准核武器,否则打你");
c2.declare("我们只有洗衣粉!!");
}
}
总结
- 中介者模式用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
- 中介者模式包含四个角色:抽象中介者用于定义一个接口,该接口用于与各同事对象之间的通信;具体中介者是抽象中介者的子类,通过协调各个同事对象来实现协作行为,了解并维护它的各个同事对象的引用;抽象同事类定义各同事的公有方法;具体同事类是抽象同事类的子类,每一个同事对象都引用一个中介者对象;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中定义的方法。
- 通过引入中介者对象,可以将系统的网状结构变成以中介者为中心的星形结构,中介者承担了中转作用和协调作用。中介者类是中介者模式的核心,它对整个系统进行控制和协调,简化了对象之间的交互,还可以对对象间的交互进行进一步的控制。
- 中介者模式的主要优点在于简化了对象之间的交互,将各同事解耦,还可以减少子类生成,对于复杂的对象之间的交互,通过引入中介者,可以简化各同事类的设计和实现;中介者模式主要缺点在于具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
- 中介者模式适用情况包括:系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解;一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象;想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类