以智能家庭项目引入中介者模式
智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等。主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:
闹铃响起->咖啡机开始做咖啡->窗帘自动落下->电视机开始播放
1.传统方案
1.1.问题分析
1)当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂
2)各个电器对象彼此联系,你中有我,我中有你,不利于松耦合
3)各个电器对象之间所传递的消息(参数)容易混乱
4)当系统增加一个新的电器对象时,或者执行流程改变时,代码的可维护性、扩展性都不理想
2.中介者模式
2.1.基本介绍
- 1.中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 2.属于行为型模式
- 比如 MVC 模式,C(Controller 控制器)是 M(Model 模型)和 V(View 视图)的中介者,在前后端交互时起到了中间人的作用。
- Mediator:抽象中介者,定义了同事对象到中介者对象的接口
- Colleague:抽象同事类
- ConcreteMediator:具体的中介者对象,实现抽象方法,需要知道所有的具体的同事类,即以一个集合来管理,并接受某个同事对象消息,完成相应的任务
- ConcreteColleague:具体的同事类,会有很多,每个同事只知道自己的行为,而不了解其他同事类的行为(方法), 但是他们都依赖中介者对象
2.2.代码实现:
- 1.具体流程:各种电器继承抽象电器类,实现其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<String,Colleague> colleagueMap;
public ConcreteMeditar(){
colleagueMap = new HashMap<String, Colleague>();
}
//将电器加入到集合中
@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);
}
}
咖啡机已经开启
电视机打开
--------
咖啡机已经关闭
电视机关闭了
3.中介者模式的注意事项和细节
1)多个类相互耦合,会形成网状结构, 使用中介者模式将网状结构分离为星型结构,进行解耦
2)减少类间依赖,降低了耦合,符合迪米特原则
3)中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
4)如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意