GOF23设计模式之中介者模式(mediator)
一、中介者模式概述
如果一个系统中对象之间的联系呈现网状结构,对象之间存在大量多对多的关系,导致关系及其复杂,这时可以引入一个中介者对象,使得各个对象只跟中介者对象打交道,从而将复杂的网络结构化为星型结构。
核心:
(1)如果一个系统中对象之间的联系呈现网状结构,对象之间存在大量的多对多关系,将导致关系及其复杂,这些对象称为“同事对象”;
(2)这时可以引入一个中介者对象,使各个同事对象只跟中介只对象打交道,将复杂的网络结构化解为星型结构。
二、中介者模式情景导入
在一个公司里边,有三个部门:财务部、市场部、研发部。假如没有总经理时,财务部给员工发工资,需要和其他两个部门打交道,市场部也要和其他两个部门打交道,研发部接收市场部需求,并且需要财务部资金支持,所有也要和其他两个部门打交道。虽然只有三个部门,但是关系却非常混乱。
实际上,每个公司都有总经理,各个部门需要和其他部门打交道时先通报总经理,总经理再通知各个相关部门,这样,关系就简单的多了。
这是一个典型的“中介者模式”,总经理起到中介、协调的作用。
三、中介者模式示例代码
1 /** 2 * 部门的接口 3 * @author CL 4 * 5 */ 6 public interface Department { 7 /** 8 * 自己的工作 9 */ 10 void selfAction(); 11 /** 12 * 对外的工作(向总经理发出申请) 13 */ 14 void outAction(); 15 }
1 /** 2 * 财务部 3 * @author CL 4 * 5 */ 6 public class Financial implements Department { 7 /** 8 * 持有中介者(总经理)的引用 9 */ 10 private Mediator m; 11 12 public Financial(Mediator m) { 13 this.m = m; 14 m.register("财务部", this); 15 } 16 17 @Override 18 public void selfAction() { 19 System.out.println("财务部本职工作-->做账!提供资金支持!"); 20 } 21 22 @Override 23 public void outAction() { 24 System.out.println("财务部对外工作-->汇报工作!收卖产品的钱!"); 25 m.command("市场部"); 26 } 27 28 }
1 /** 2 * 市场部 3 * @author CL 4 * 5 */ 6 public class Market implements Department { 7 /** 8 * 持有中介者(总经理)的引用 9 */ 10 private Mediator m; 11 12 public Market(Mediator m) { 13 this.m = m; 14 m.register("市场部", this); 15 } 16 17 @Override 18 public void selfAction() { 19 System.out.println("市场部本职工作-->跑业务!卖产品!"); 20 } 21 22 @Override 23 public void outAction() { 24 System.out.println("市场部对外工作-->汇报工作!申请资金支持!"); 25 m.command("财务部"); 26 } 27 28 }
1 /** 2 * 研发部 3 * @author CL 4 * 5 */ 6 public class Development implements Department { 7 /** 8 * 持有中介者(总经理)的引用 9 */ 10 private Mediator m; 11 12 public Development(Mediator m) { 13 this.m = m; 14 m.register("研发部", this); 15 } 16 17 @Override 18 public void selfAction() { 19 System.out.println("研发部本职工作-->研发产品!"); 20 } 21 22 @Override 23 public void outAction() { 24 System.out.println("研发部对外工作-->汇报工作!寻找资金支持!"); 25 m.command("财务部"); 26 } 27 28 }
1 /** 2 * 中介者的接口(总经理) 3 * @author CL 4 * 5 */ 6 public interface Mediator { 7 /** 8 * 各部门向总经理备案 9 * @param dName 部门名称 10 * @param d 部门 11 */ 12 void register(String dName, Department d); 13 14 /** 15 * 向其他部门发送任务 16 * @param dName 部门名称 17 */ 18 void command(String dName); 19 }
1 import java.util.HashMap; 2 import java.util.Map; 3 4 /** 5 * 总经理类(中介) 6 * @author CL 7 * 8 */ 9 public class President implements Mediator { 10 private Map<String, Department> map; 11 12 public President() { 13 map = new HashMap<String, Department>(); 14 } 15 16 @Override 17 public void register(String dName, Department d) { 18 map.put(dName, d); 19 } 20 21 @Override 22 public void command(String dName) { 23 map.get(dName).selfAction(); 24 } 25 26 }
测试:
1 /** 2 * 测试中介者模式 3 * @author CL 4 * 5 */ 6 public class Client { 7 8 public static void main(String[] args) { 9 Mediator m = new President(); 10 11 //各部门向总经理备案 12 Market market = new Market(m); 13 Financial financial = new Financial(m); 14 Development development = new Development(m); 15 16 //市场部 17 market.selfAction(); 18 market.outAction(); 19 20 System.out.println("-------------------------------"); 21 22 //财务部 23 financial.outAction(); 24 25 System.out.println("-------------------------------"); 26 27 //研发部 28 development.outAction(); 29 30 } 31 }
控制台输出:
市场部本职工作-->跑业务!卖产品! 市场部对外工作-->汇报工作!申请资金支持! 财务部本职工作-->做账!提供资金支持! ------------------------------- 财务部对外工作-->汇报工作!收卖产品的钱! 市场部本职工作-->跑业务!卖产品! ------------------------------- 研发部对外工作-->汇报工作!寻找资金支持! 财务部本职工作-->做账!提供资金支持!
四、中介者模式常见开发应用场景
(1)MVC 模式(其中 C 控制器就是一个中介者对象,M 和 V 都和 C 打交道);
(2)窗口游戏游戏,窗口软件开发中窗口对象也是一个中介者对象;
(3)图形界面开发 GUI 中,多个组件之间的交互,可以通过引入一个中介者对象来解决,可以是整体的窗口对象或者 DOM对象;
(4)…………