以智能家庭项目引入中介者模式
智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等。主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:
闹铃响起->咖啡机开始做咖啡->窗帘自动落下->电视机开始播放
传统方案
问题分析
1)当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂
2)各个电器对象彼此联系,你中有我,我中有你,不利于松耦合
3)各个电器对象之间所传递的消息(参数)容易混乱
4)当系统增加一个新的电器对象时,或者执行流程改变时,代码的可维护性、扩展性都不理想
中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
属于行为型模式
比如 MVC 模式,C(Controller 控制器)是 M(Model 模型)和 V(View 视图)的中介者,在前后端交互时起到了中间人的作用。
具体流程:各种电器继承抽象电器类,实现其sendMessage方法,初始化时将其加入到中介者的集合进行管理,当电器使用sendMessage方法发送消息给中介者时,中间者使用getMessage方法进行接收,通过电器名和消息类型来进一步判断接下来如何执行。
抽象电器类
- //电器类
- public abstract class Colleague {
-
- //中介者
- private Mediator mediator;
- //电器名称
- private String name;
-
- public Colleague(Mediator mediator, String name) {
- this.mediator = mediator;
- this.name = name;
- }
-
- public Mediator getMediator() {
- return mediator;
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * 向中介者发送消息
- * @param stateChange 消息类型
- */
- public abstract void sendMessage(int stateChange);
-
- }
闹钟类
- public class Alarm extends Colleague {
-
- public Alarm(Mediator mediator, String name){
- super(mediator, name);
- //在中介者中添加电器
- mediator.Register(name, this);
- }
-
- //设置闹钟
- public void setAlarm(int stateChange){
- sendMessage(stateChange);
- }
-
- //向中介者发送消息
- @Override
- public void sendMessage(int stateChange) {
- //中介者接收消息
- getMediator().getMessage(stateChange, getName());
- }
- }
咖啡机类
- public class Coffee extends Colleague{
-
- public Coffee(Mediator mediator, String name) {
- super(mediator, name);
- //在中介者中添加电器
- mediator.Register(name, this);
- }
-
- public void startCoffee(){
- System.out.println("咖啡机已经开启");
- }
-
- public void FinishCoffee(){
- System.out.println("咖啡机已经关闭");
- }
-
- //向中介者发送消息
- @Override
- public void sendMessage(int stateChange) {
- //中介者接收消息
- getMediator().getMessage(stateChange, getName());
- }
- }
电视机类
- public class TV extends Colleague {
-
- public TV(Mediator mediator, String name) {
- super(mediator, name);
- //在中介者中添加电器
- mediator.Register(name, this);
- }
-
- public void startTV(){
- System.out.println("电视机打开");
- }
-
- public void finishTV(){
- System.out.println("电视机关闭了");
- }
- //给中间者发送消息
- @Override
- public void sendMessage(int stateChange) {
- //中介者接收消息
- getMediator().getMessage(stateChange, getName());
- }
- }
抽象中介者
- public abstract class Mediator {
- /**
- * 添加电器
- * @param colleagueName 电器名称
- * @param colleague 电器
- */
- public abstract void Register(String colleagueName, Colleague colleague);
-
- /**
- * 接收电器消息
- * @param stateChange 消息类型
- * @param colleagueName 电器名称
- */
- public abstract void getMessage(int stateChange, String colleagueName);
- }
具体中介者
- public class ConcreteMeditar extends Mediator{
-
- //存入具体的电器对象
- private HashMap
colleagueMap; -
- public ConcreteMeditar(){
- colleagueMap = new HashMap
(); - }
-
- //将电器加入到集合中
- @Override
- public void Register(String colleagueName, Colleague colleague) {
- colleagueMap.put(colleagueName, colleague);
- }
-
- //接收电器的消息
- @Override
- public void getMessage(int stateChange, String colleagueName) {
- if(colleagueMap.get(colleagueName) instanceof Alarm){
- if(stateChange == 100){
- ((Coffee)colleagueMap.get("Coffee")).startCoffee();
- ((TV)colleagueMap.get("TV")).startTV();
- }else if(stateChange == 101){
- ((Coffee)colleagueMap.get("Coffee")).FinishCoffee();
- ((TV)colleagueMap.get("TV")).finishTV();
- }
- }
- }
- }
测试
- public class Client {
- public static void main(String[] args) {
- //创建中介者对象
- ConcreteMeditar concreteMeditar = new ConcreteMeditar();
- //具体电器
- Alarm alarm = new Alarm(concreteMeditar, "Alarm");
- Coffee coffee = new Coffee(concreteMeditar, "Coffee");
- TV tv = new TV(concreteMeditar, "TV");
-
- //开咖啡机,开电视
- alarm.setAlarm(100);
- System.out.println("--------");
- //关咖啡机,关电视
- alarm.setAlarm(101);
- }
- }
咖啡机已经开启 电视机打开 -------- 咖啡机已经关闭 电视机关闭了
1)多个类相互耦合,会形成网状结构, 使用中介者模式将网状结构分离为星型结构,进行解耦
2)减少类间依赖,降低了耦合,符合迪米特原则
3)中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
4)如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意