中介者模式
**中介者模式(Mediator Pattern):**用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
角色
Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
中介者模式的核心在于中介者类的引入,在中介者模式中,中介者类承担了两方面的职责:
中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中介者在结构上的支持。
协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致的和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。
*实例:实现同事间的协调合作
源代码:*
package org.zangyu.Middleman;
public class Middleman {
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreteMediator m=new ConcreteMediator();
//让两个具体同时类认识中介者
Colleague1 c1=new Colleague1(m);
Colleague2 c2=new Colleague2(m);
//让中介者认识各个具体同事类
m.setColleague1(c1);
m.setColleague2(c2);
//具体同事发消息都是通过中介者来发的
c1.Send("吃了吗?");
c2.Send("没呢,一起?");
}
}
abstract class Colleague
{
protected Mediator mediator;
//构造方法,得到中介者对象
public Colleague(Mediator mediator)
{
this.mediator=mediator;
}
}
abstract class Mediator
{
//定义一个抽象的发送消息方法,得到同事对象和发送的消息
//colleague发送message
public abstract void Send(String message,Colleague colleague);
}
class Colleague1 extends Colleague
{
public Colleague1(Mediator mediator) {//让具体同事1认识中介者
super(mediator);
// TODO Auto-generated constructor stub
}
public void Send(String message)
{
mediator.Send(message, this);//Colleague1发送message
}
public void Notify(String message)
{
System.out.println("同事1得到消息:"+message);
}
}
class Colleague2 extends Colleague
{
public Colleague2(Mediator mediator) {//让具体同事2认识中介者
super(mediator);
// TODO Auto-generated constructor stub
}
public void Send(String message)
{
mediator.Send(message, this);//Colleague2发送message
}
public void Notify(String message)
{
System.out.println("同事2得到消息:"+message);
}
}
//具体中介者类
class ConcreteMediator extends Mediator
{
private Colleague1 colleague1;//定义具体同事1
private Colleague2 colleague2;//定义具体同事2
public Colleague1 getColleague1() {
return colleague1;
}//得到具体同事1
public void setColleague1(Colleague1 colleague1) {
this.colleague1 = colleague1;
}//设置具体同事1,让中介者认识具体同事1
public Colleague2 getColleague2() {
return colleague2;
}
public void setColleague2(Colleague2 colleague2) {
this.colleague2 = colleague2;
}
//重写发送消息的方法,根据对象做出选择判断,通知具体的同同事对象
@Override
public void Send(String message, Colleague colleague) {
// TODO Auto-generated method stub
//如果colleague1发送消息,则将消息通知colleague2
if(colleague==colleague1)
{
colleague2.Notify(message);
}else {
colleague1.Notify(message);
}
}
}
实例:国家之间关系测处理
源代码:
package org.zangyu.Middleman;
public class Middleman2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
UNS uns =new UNS();//联合国安理会
USA usa=new USA(uns);//美国联系安理会
Iraq iraq=new Iraq(uns);//伊拉克联系安理会
uns.setUsa(usa);//安理会会应美方
uns.setIraq(iraq);//安理会会应伊拉克
usa.Declare("不准研制核武器");//美国发送消息
iraq.Declare("没有");//伊拉克收到并发送消息
}
}
//联合国机构类——中介者
abstract class UN
{
//声明
public abstract void Declare(String message,Country country);
}
//国家类——抽象同事类
abstract class Country
{
protected UN un;
public Country(UN un)
{
this.un=un;
}
}
//美国类——具体同事1
class USA extends Country
{
public USA(UN un) {
super(un);
// TODO Auto-generated constructor stub
}
//发送消息
public void Declare(String message)
{
un.Declare(message, this);
}
//获取消息
public void GetMessage(String message)
{
System.out.println("美国收到消息:"+message);
}
}
//伊拉克类——具体同事2
class Iraq extends Country
{
public Iraq(UN un) {//认识联合国
super(un);
// TODO Auto-generated constructor stub
}
//发送消息
public void Declare(String message)
{
un.Declare(message, this);
}
//获取消息
public void GetMessage(String message)
{
System.out.println("伊拉克收到消息:"+message);
}
}
//联合国安理会类——具体中介者
class UNS extends UN{
private USA usa;
private Iraq iraq;
//美国
public USA getUsa() {
return usa;
}
public void setUsa(USA usa) {
this.usa = usa;
}
//伊拉克
public Iraq getIraq() {
return iraq;
}
public void setIraq(Iraq iraq) {
this.iraq = iraq;
}
@Override
public void Declare(String message, Country country) {
// TODO Auto-generated method stub
if(country==usa)
{
iraq.GetMessage(message);
}else {
usa.GetMessage(message);
}
}
}
使用场景
使用终结者模式的场合
1.一组定义良好的对象,现在要进行复杂的通信。
2.定制一个分布在多个类中的行为,而又不想生成太多的子类。
可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。呵呵~~~
使用中介者模式的优点:
1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。
2.提高系统的灵活性,使得系统易于扩展和维护。
使用中介者模式的缺点:
中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。
以上部分摘取自朱红梅老师2020年5月的课件。