中介者模式(Mediator)
动机:在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一-种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。所以可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系。
问题引入——联合国沟通世界各国
- 在公司内部,有很多部门,员工,为了完成一定的任务,“同事”,们肯定有许多需要相互配合,交流的过程。但是多对多的杂乱的联系网络而造成工作效率低下。此时就需要一位“中介者”给各个“同事”分配任务。
- 电脑拥有主板才能完成交互
类似的,为了减少关联关系,就要有一个专门处理对象间交互和通信的类,这个中介者就是中介者模式。
作用:
- Mediator模式将对象间的交互和通信封装在一个类中,各个对象间的通信不必显式去声明和引用,大大降低了系统的复杂性能
- Mediator模式还带来了系统对象间的松耦合。
- 通过中介者模式,可以将复杂关系的网状结构变成结构简单的以中介者为核心的星形结构,每个对象不再和它与之关联的对象直接发生相互作用,而是通过中介者对象来与另一个对象发生相互作用。
定义:用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖→运行时依赖),从而使其耦合松散(管理变化),而且可以独立地改变它们之间的交互。
//抽象中介类
abstract class Mediator{
//定义一个抽象的发送消息的方法,得到同事对象和发送的消息
public abstract void Send(String message,Colleague colleague);
}
//抽象同事类
abstract class Colleague{
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator=mediator;
}
}
//具体同事类1
class ConcreteColleague1 extends Colleague{
public ConcreteColleague1(Mediator mediator) {
super(mediator);
// TODO Auto-generated constructor stub
}
public void Send(String message) {
mediator.Send(message, this);
}
public void Notify(String message) {
System.out.println("同事1得到的信息:"+message);
}
}
class ConcreteColleague2 extends Colleague{
public ConcreteColleague2(Mediator mediator) {
super(mediator);
// TODO Auto-generated constructor stub
}
public void Send(String message) {
mediator.Send(message, this);
}
public void Notify(String message) {
System.out.println("同事2得到的信息:"+message);
}
}
//具体中介类
class ConcreteMediator extends Mediator{
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public ConcreteColleague1 getColleague1() {
return colleague1;
}
public void setColleague1(ConcreteColleague1 colleague1) {
this.colleague1 = colleague1;
}
public ConcreteColleague2 getColleague2() {
return colleague2;
}
public void setColleague2(ConcreteColleague2 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);
}
}
}
public class text {
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreteMediator m=new ConcreteMediator();
//让两个具体同事类认识中介者对象
ConcreteColleague1 c1=new ConcreteColleague1(m);
ConcreteColleague2 c2=new ConcreteColleague2(m);
//让中介者认识各个具体同事类
m.setColleague1(c1);
m.setColleague2(c2);
//具体同事类对象发送消息都是通过中介者转发的
c1.Send("你吃饭了吗?");//找个人一起吃饭
c2.Send("还没呢,你请客不?");
}
}
中介者模式中,中介者对象
- 在结构上起到了中转作用
- 行为上起到了协助作用。将同事成员之间的关系行为进行分离和封装。
- 减少了同事类之间的耦合度,使得他们可以独立改变和复用。
//联合国机构
abstract class UnitedNations{
public abstract void Declare(String message,Country colleague);
}
//国家类
abstract class Country{
protected UnitedNations mediator;
public Country(UnitedNations mediator) {
this.mediator=mediator;
}
}
class USA extends Country{
public USA(UnitedNations mediator) {
super(mediator);
// TODO Auto-generated constructor stub
}
public void Declare(String message) {
mediator.Declare(message, this);
}
public void GetMessage(String message) {
System.out.println("美方获得对方信息:"+message);
}
}
class Iraq extends Country{
public Iraq(UnitedNations mediator) {
super(mediator);
// TODO Auto-generated constructor stub
}
public void Declare(String message) {
mediator.Declare(message, this);
}
public void GetMessage(String message) {
System.out.println("伊拉克获得对方信息:"+message);
}
}
//联合国安全理事会
class UnitedNationsSecurityCouncil extends UnitedNations{
private USA colleague1;
private Iraq colleague2;
public USA getColleague1() {
return colleague1;
}
public void setColleague1(USA colleague1) {
this.colleague1 = colleague1;
}
public Iraq getColleague2() {
return colleague2;
}
public void setColleague2(Iraq colleague2) {
this.colleague2 = colleague2;
}
@Override
public void Declare(String message, Country colleague) {
// TODO Auto-generated method stub
if(colleague==colleague1) {
colleague2.GetMessage(message);
}else {
colleague1.GetMessage(message);
}
}
}
public class text{
public static void main(String[] args){
UnitedNationsSecurity UNSC=new UnitedNationsSecurity();
USA c1=new USA(UNSC);
Iraq c2=new Iraq(UNSC);
UNSC.setColleague1(c1);
UNSC.setColleague2(c2);
c1.Declare("不准研发核武器,否则开战");
c2.Declare("没研发,开战就开战");
}
}
优点:
- Mediator模式是一科很有用并且很常用的模式,它将对象间的通信封装到一个类中,将多对多的通信转化为一对多的通信,降低了系统的复杂性。
- Mediator还获得系统解耦的特性,通过Mediator,各个Colleague就不必维护各自通信的对象和通信协议,降低了系统的耦合性, Mediator和各个Colleague就可以相互独立地修改了。
- Mediator模式还有一个很显著的特点就是将控制集中,集中的优点就是便于管理,也正符合了OO设计中的每个类的职责要单一和集中的原则。
缺点:
控制的集中化把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。
什么时候使用中介者模式呢?
- 如果一组对象之间的通信方式比较复杂,导致相互依赖、结构混乱,可以采用中介者模式,把这些对象相互的交互管理起来。
- 如果一个对象引用很多的对象,并直接跟这些对象交互,导致难以复用该对象,可以采用中介者模式,把这个对象跟其他对象的交互封装到中介者对象里面。