中介者(调停者)模式--设计模式
前言
现实生活中,常常会出现对象之间存在复杂的交互关系, 这种交互关系可能会出现网状结或者星形结构,如果将这种结构更改的话,会大大降低之间的耦合性, 这时只需要找个“中介者”就可以解决.
假如科技发达之后, 家里设备是智能化的,而小明有个习惯-洗澡,喜欢听歌,此时还要把窗帘拉上.
小明希望家里的洗浴设备,音响设备,窗帘设备能协同合作, 不管操作哪个设备,其他设备都可以响应.
现在很明显可以看出来, 有三个对象,也就是三种设备, 程序看起来也很简单, 只要打开了一种设备,然后再打开另外两个设备, 只要在一个设备的类放入另外两个设备的引用.
这个程序最主要的功能就是一个类里完成了对另外两个类的引用, 但是设计有两个主要缺陷:
- 一旦窗帘坏掉,响应更换,那我们就需要让那个新窗帘设备建立新的连接与其他设备
- 如果有其他需求, 比如洗澡要把门锁好,更加麻烦
解决上面的问题,引入了中介者模式
定义与特点
2.1 定义
中介者(Mediator)模式: 定义一个中介对象来封装一系列对象的交互操作,使原有对象之间的耦合松散,以及独立之间的交互,中介者模式又叫做调停模式
2.2 特点--优缺点
2.2.1 优点
- 通过对象之间彼此解藕,增加了对象的复用性
- 通过控制逻辑集中, 简化了系统维护
- 通过中介者将一对多变为了一对一,便于理解
2.2.2 缺点
- 当引入的对象类越来越多时,中介者的指责就会变得更大, 导致类变的臃肿,以至于系统难以维护
角色与结构
3.1 角色
中介者模式的实现关键在于找出“中介者”
- 抽象中介者(Mediator)角色: 中介者的接口, 提供了同事对象注册与转发同事对象信息的抽象方法.
- 具体中介者(ConcreteMediator)角色: 实现中介者的接口, 定义个list来管理同事对象,协调各个同事角色之间的交互关系
- 抽象同事类(Colleague)角色: 定义同事类的接口, 保存中介者对象,提供同事对象交互的抽象方法, 实现所有相互影响的同事类的公共功能
- 具体同事类(Concrete Colleague)角色: 抽象同事类的实现者, 当需要与其他同事对象交互时,由中介者对象负责后续的交互。
3.2 结构图
代码
4.1 抽象同事类
package mediator_12; public abstract class SmartDevice { //相关设备打开之后 使其进入准备状态 public abstract void readyState(String instruction); //操作该设备 public abstract void operateDevice(String instruction, SmartMediator mediator); }
4.2 具体同事类1(窗帘设备)
package mediator_12; public class CurtainDevice extends SmartDevice{ public void operateDevice(String instruction,SmartMediator mediator) { System.out.println("窗帘已"+instruction);//通过传入指令,打开或关闭窗帘 mediator.curtain(instruction);//窗帘通过中介者唤醒音乐设备和洗浴设备 } public void readyState(String instruction) { //如果其他设备开启则调用此方法,唤醒窗帘 System.out.println("窗帘设备准备"+instruction); } }
4.3 具体同事类2(音响设备)
package mediator_12; public class MusicDevice extends SmartDevice{ public void operateDevice(String instruction,SmartMediator mediator) { System.out.println("音乐设备已"+instruction); mediator.music(instruction); } public void readyState(String instruction) { System.out.println("音乐设备准备"+instruction); } }
4.4 具体同事类3(洗浴设备)
package mediator_12; public class BathDevice extends SmartDevice{ public void operateDevice(String instruction, SmartMediator mediator) { System.out.println("洗浴设备"+instruction); mediator.bath(instruction); } public void readyState(String instruction) { System.out.println("洗浴设备正在准备"+instruction); } }
4.5 抽象中介者(中介设备)
package mediator_12; public abstract class SmartMediator { //保留所有设备的引用是为了当接收指令时可以唤醒其他设备的操作 SmartDevice bd; SmartDevice md; SmartDevice cd; public SmartMediator(SmartDevice bd, SmartDevice md, SmartDevice cd) { super(); this.bd = bd; this.md = md; this.cd = cd; } public abstract void music(String instruction); public abstract void curtain(String instruction); public abstract void bath(String instruction); }
4.6 具体中介者
package mediator_12; public class ConcreteMediator extends SmartMediator{ public ConcreteMediator(SmartDevice bd, SmartDevice cd, SmartDevice md) { super(bd, cd, md); } public void music(String instruction) {//音乐被唤醒后,使其他设备进入准备状态 cd.readyState(instruction);//调用窗帘的准备方法 bd.readyState(instruction);//调用洗浴设备的准备方法 } public void curtain(String instruction) { md.readyState(instruction); bd.readyState(instruction); } public void bath(String instruction) { cd.readyState(instruction); md.readyState(instruction); } }
4.7 客户端
package mediator_12; public class Client { public static void main(String[] args) { SmartDevice bd=new BathDevice(); SmartDevice cd=new CurtainDevice(); SmartDevice md=new MusicDevice(); SmartMediator sm=new ConcreteMediator(bd, cd, md);//把设备引用都保存在调停者中 cd.operateDevice("open",sm); //开启窗帘 md.operateDevice("close",sm);//关闭音乐 } }
总结
中介者模式封装了一系列对象交互, 中介者各对象不需要彼此联系引用对方相互作用, 从而耦合松散.达到了解藕的目的.
希望通过本篇博客,增深大家对中介者模式的理解,谢谢大家!!!