中介者模式听名字就能想到也是一种为了解决耦合度的设计模式,其实中介者模式在结构上与观察者、命令模式十分相像;而应用目的又与结构模式“门面模式”有些类似。但区别于命令模式的是大多数中介者角色对于客户程序是透明的。固然形成这种区别的缘由是因为他们要达到的目的不一样。 html
中介者模式是指用一个中介对象来封装一系列的对象交互。中介者使个对象不须要显示的相互引用,从而使其耦合松散,并且能够独立地改变它们之间的交互。简单地说,将原来两个直接引用或者依赖的对象拆开,在中间加入一个“中介”对象,使得两头的对象分别与“中介”对象引用或者依赖。设计模式
例以下面这个结构,若是每一个元素两两之间要产生联系,关系就会变得错综复杂。ide
可是加了中介者以后,相互之间就能够解耦了。变成以下的关系结构。post
和二跟老纪都是朝廷大臣,可是互相看不顺眼,在皇上面前和和睦气,背地里各自互相参对方。固然有时候皇上颁布旨意时让两个大臣一块儿合做去完成任务,他们也会相互合做的。和二跟老纪都想收拾对方,可是奈何双方官职不相上下,因此当想收拾对方时就会经过皇上来实现,这个时候咱们就当皇上理解为中介者(感受有点牵强,就这样吧😂)。下面用代码来实现这个过程。学习
官员抽象类测试
/** * 官员(大臣)抽象类 */ public abstract class Official { protected Monarch monarch; /** * 每一个官员必然要与君主有联系 * @param monarch */ public Official(Monarch monarch){ this.monarch = monarch; } /** * 在抽象官员类中添加与中介者取得联系的方法 * @param monarch */ public void setMonarch(Monarch monarch){ this.monarch = monarch; } }
君主抽象类this
/** * 君主抽象类 */ public abstract class Monarch { /** * 君主保持着和各个官员的联系 */ protected ConcurrentHashMap<String,Official> officials = new ConcurrentHashMap<>(); /** * 录用官员 * @param name * @param official */ public void addOfficial(String name,Official official){ this.officials.put(name,official); } /** * 将官员革职查办 * @param name */ public void removeOfficial(String name){ this.officials.remove(name); } /** * 处理各个官员之间的互相参奏的折子 * @param name * @param method */ public abstract void execute(String name,String method); }
老纪url
/** * 老纪 */ public class LaoJi extends Official{ /** * 每一个官员必然要与君主有联系 * * @param monarch */ public LaoJi(Monarch monarch) { super(monarch); } /** * 作好本职工做 */ public void self(){ System.out.println("启奏皇上,臣老纪参与编写的四库全书已经完成。"); } /** * 参其余官员或与其余官员合做 */ public void out(){ System.out.println("启奏皇上,臣老纪要参和二一本,秀女选拔工做到如今还没完成,理应当革职查办。"); super.monarch.execute("heEr","self"); } }
和二spa
/** * 和二 */ public class HeEr extends Official { /** * 每一个官员必然要与君主有联系 * * @param monarch */ public HeEr(Monarch monarch) { super(monarch); } /** * 作好本职工做 */ public void self(){ System.out.println("启奏皇上,臣和二掌管的秀女选拔工做已经完成。"); } /** * 参其余官员或与其余官员合做 */ public void out(){ System.out.println("启奏皇上,臣和二要参老纪一本,四库全书到目前还没编写完成,理应问斩。"); super.monarch.execute("laoji","self"); } }
黄三(乾隆皇上)设计
/** * 黄三(皇上) */ public class HuangSan extends Monarch { /** * 处理各个官员之间的互相参奏的折子 * * @param name * @param method */ @Override public void execute(String name, String method) { //作好本身分内的事情 if("self".equals(method)){ if("laoji".equals(name)){ ((LaoJi)super.officials.get(name)).self(); }else { ((HeEr)super.officials.get(name)).self(); } //我要参别人一本 }else { if("laoji".equals(name)){ ((LaoJi)super.officials.get(name)).out(); }else { ((LaoJi)super.officials.get(name)).out(); } } } }
测试类
public class Client { public static void main(String[] args) { //建立一个君主 Monarch monarch = new HuangSan(); //建立两个官员 LaoJi laoJi = new LaoJi(monarch); HeEr heEr = new HeEr(monarch); //君主和两个官员创建关系 monarch.addOfficial("laoji",laoJi); monarch.addOfficial("heEr",heEr); //有本奏上,无本退朝。 //laoJi.self(); laoJi.out(); System.out.println("---------------启奏完毕"); //heEr.self(); heEr.out(); System.out.println("---------------启奏完毕"); } }
运行结果
启奏皇上,臣老纪要参和二一本,秀女选拔工做到如今还没完成,理应当革职查办。 启奏皇上,臣和二掌管的秀女选拔工做已经完成。 ---------------启奏完毕 启奏皇上,臣和二要参老纪一本,四库全书到目前还没编写完成,理应问斩。 启奏皇上,臣老纪参与编写的四库全书已经完成。 ---------------启奏完毕
上面的这个例子就是实现了中介者模式,皇上成了老纪跟和二的中介者。这样使得两位大臣也不用直接互怼了,除了干好本身的本职工做还能够督促其余同事完成工做。
中介者模式的组成角色以下所示
抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口,用于各同事角色之间的通讯。上面例子中君主类表明的就是这个角色。
具体中介者(ConcreteMediator)角色:具体中介者角色经过协调各同事角色,实现协做行为,为此它要指导并引用各个同事角色。上面例子中皇上表明的就是这个角色。
同事(Colleague)角色:每个同事角色都知道对应的具体中介者角色,并且与其余的同事角色通讯的时候,必定要经过中介者角色协做。上面的例子中老纪跟和二就是表明的这个角色。
中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构,在这个星型结构中,使用中介者对象与其余对象的一对多关系来取代原有对象之间的多对多关系。
一、中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护扩展,将本来难以理解的网状结构转换成相对简单的星型结构。
二、中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,咱们能够独立的改变和复用每个同事和中介者,增长新的中介者和新的同事类都比较方便,更好的符合“开闭原则”。
三、能够减小子类生成,中介者将本来分布于多个对象间的行为集中在一块儿,改变这些行为只需生成新的中介者子类便可,这使得各个同事类可被重用,无须对同事类进行扩展。
在具体中介者类中包含了大量同事之间的交互细节,可能会致使具体中介者类很是复杂,使得系统难以维护。
一、系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
二、 一个对象因为引用了其余不少对象而且直接和这些对象通讯,致使难以复用该对象。
三、想经过一个中间类来封装多个类中的行为,而又不想生成太多的子类。能够经过引入中介者类来实现,在中介者中定义对象交互的公共行为,若是须要改变行为则能够增长新的具体中介者类。
想了解更多的设计模式请查看Java设计模式学习记录-GoF设计模式概述。