中介者模式(MEDIATOR),又称调停者模式,通过使用一个中介者对象来封装一系列的对象交互,属于对象行为型模式。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。现实生活中,到处充斥着中介者模式的身影。上到庄严的法院,下到为程序员带来福音的婚姻介绍所或交友平台,还有可恶的房产中介,都是中介者模式的体现。比如,你参加一个相亲活动,20多对男女如饥似渴地寻找着自己的另一半。如果不是一见钟情,你就需要了解20多个女生,不排除男生的话,就是40多个人的喜好,性格是否符合自己,这简直就是灾难!如果相亲活动举办地比较符合人情,有个官方的媒婆,她负责将20多对男女根据彼此的喜好,性格进行配对,这样就减少了相亲者之间的耦合关系,节省相亲者们的时间和精力,此乃中介者模式之妙用也。
一、使用场景
1、一组对象以定义良好但是复杂的方式进行通信,比如网络状的结构,这样产生的相互依赖关系结构混乱且难以理解。可以使用中介者模式对复杂依赖关系进行改造,以获取更好的灵活性。
2、一个对象引用其他很多对象并且直接与这些对象通信,导致该对象难以复用。中介者模式将对象的相互依赖关系转换为中介者和对象的依赖关系,使对象能够灵活复用。
3、想定制一个分布在多个类中的行为,而又不想生成太多的子类。
二、UML图
三、Java实现
package study.patterns.mediator; import java.util.ArrayList; import java.util.List; /** * 中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构, * 在这个星型结构中,使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系。 * 中介者模式在事件驱动类软件中应用较为广泛,特别是基于GUI(Graphical User Interface, * 图形用户界面)的应用软件,此外,在类与类之间存在错综复杂的关联关系的系统中, * 中介者模式都能得到较好的应用。 * @author qbg */ public class MediatorPattern { public static void main(String[] args) { List<Person> ps = new ArrayList<Person>(); Person b0 = new Boy(); ps.add(b0); Person b1 = new Boy(); ps.add(b1); Person g0 = new Girl(); ps.add(g0); Person g1 = new Girl(); ps.add(g1); Mediator mediator = new ConcreteMediator(ps); b0.setInterest("创业"); b0.setMediator(mediator); b1.setInterest("挣钱"); b1.setMediator(mediator); g0.setInterest("逛街"); g0.setMediator(mediator); g1.setInterest("持家"); g1.setMediator(mediator); b0.interest("持家"); System.out.println("==========男女有别==============="); g0.interest("挣钱"); } } /** * 中介者抽象接口 */ interface Mediator{ public void interestChanged(Person p); } /** * 具体中介者,充当媒婆的角色。 */ class ConcreteMediator implements Mediator{ private List<Person> miai; //相亲队伍 public ConcreteMediator(List<Person> ps){ this.miai = ps; } /** * 相亲者兴趣改变时进行响应,重新匹配候选人. * 封装同事对象之间的交互. */ @Override public void interestChanged(Person p) { boolean succeed = false; Person candidate = null; for(Person person : miai){ //不是相亲者本身且兴趣相同则匹配成功! if(person!=p && p.interest.equals(person.interest)){ succeed = true; candidate = person; break; } } p.update(succeed); if(candidate!=null){ candidate.update(succeed); } } } /** * 人,抽象同事类 */ abstract class Person{ protected Mediator mediator;//中介者引用 protected String interest;//兴趣 public void setMediator(Mediator m){ this.mediator = m; } public void setInterest(String in){ this.interest = in; } public void interest(String interest){ this.interest = interest; mediator.interestChanged(this); } public abstract void update(boolean succeed); } /** * 男生,具体同事类 */ class Boy extends Person{ @Override public void update(boolean succeed) { if(succeed){ System.out.println("相亲成功,大喝一顿!!!"); }else{ System.out.println("相亲失败,明天再战!!!"); } } } /** * 女生,具体同事类 */ class Girl extends Person{ @Override public void update(boolean succeed) { if(succeed){ System.out.println("找到白马王子了,去KTV狂欢!"); }else{ System.out.println("黑驴都没找到,全是骡子,呜呜...."); } } }运行结果:
相亲成功,大喝一顿!!! 找到白马王子了,去KTV狂欢! ==========男女有别=============== 找到白马王子了,去KTV狂欢! 相亲成功,大喝一顿!!!
四、模式优缺点
优点:
1、减少了子类的生成。中介者Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需生成Mediator的子类即可,这样各个同事类(Colleague类)可被重用。
2、将各Colleague解耦。Mediator有利于各Colleague间的松耦合,你可以独立的改变和复用各Colleague和Mediator类。
3、简化了对象协议。用Mediator和各Colleague间的一对多的交互来代替多对多的交互,使对象关系更易于理解,维护和扩展。
4、对对象如何协作进行了抽象。中介者模式很好的将使用者的注意力从对象各自本身的行为转移到它们之间的交互上。
5、使控制集中化。中介者模式将交互的复杂性变为中介者的复杂性。
缺点:
1、由于中介者模式将控制集中到中介者身上,可能会导致中介者过于复杂而难于维护。