java设计模式之中介者模式

中介者模式(Mediator Pattern)

基本介绍

  1. 中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其解耦松散。而且可以独立地改变它们之间的交互。
  2. 中介者模式属于行为型模式。
  3. 比如MVC模式,Controller控制器是Model和View视图的中介者,再前后端交互时起到了中间人的作用。

原理类图

Mediator: 就是抽象中介者,定义了同事对象到中介者对象的接口。

Colleague: 是抽象同事类。

ConcreteMediator: 具体的中介者对象,实现抽象方法,他需要知道所有的具体同事类,即以一个集合来管理HashMap,并接收某个同事对象消息,完成相应的任务。

ConcreteColleague: 具体的同事类,会有很多,每个同事只知道自己行为,而不了解其他同事类的行为,但是他们都依赖中介者对象。

应用实例

  1. 智能家庭包括各种设备,闹钟,咖啡机,电视机,窗帘等。
  2. 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程是:闹铃响起,咖啡机开始做咖啡,窗帘自动落下,电视机开始播放。

思路分析类图:

代码如下:

java 复制代码
//同事抽象类
public abstract class Colleague {
	private Mediator mediator;
	public String name;

	public Colleague(Mediator mediator, String name) {

		this.mediator = mediator;
		this.name = name;

	}

	public Mediator GetMediator() {
		return this.mediator;
	}

	public abstract void SendMessage(int stateChange);
}

public abstract class Mediator {
	//将给中介者对象,加入到集合中
	public abstract void Register(String colleagueName, Colleague colleague);

	//接收消息, 具体的同事对象发出
	public abstract void GetMessage(int stateChange, String colleagueName);

	public abstract void SendMessage();
}

//具体的中介者类
public class ConcreteMediator extends Mediator {
	//集合,放入所有的同事对象
	private HashMap<String, Colleague> colleagueMap;
	private HashMap<String, String> interMap;

	public ConcreteMediator() {
		colleagueMap = new HashMap<String, Colleague>();
		interMap = new HashMap<String, String>();
	}

	@Override
	public void Register(String colleagueName, Colleague colleague) {
		// TODO Auto-generated method stub
		colleagueMap.put(colleagueName, colleague);

		// TODO Auto-generated method stub

		if (colleague instanceof Alarm) {
			interMap.put("Alarm", colleagueName);
		} else if (colleague instanceof CoffeeMachine) {
			interMap.put("CoffeeMachine", colleagueName);
		} else if (colleague instanceof TV) {
			interMap.put("TV", colleagueName);
		} else if (colleague instanceof Curtains) {
			interMap.put("Curtains", colleagueName);
		}

	}

	//具体中介者的核心方法
	//1. 根据得到消息,完成对应任务
	//2. 中介者在这个方法,协调各个具体的同事对象,完成任务
	@Override
	public void GetMessage(int stateChange, String colleagueName) {
		// TODO Auto-generated method stub

		//处理闹钟发出的消息
		if (colleagueMap.get(colleagueName) instanceof Alarm) {
			if (stateChange == 0) {
				((CoffeeMachine) (colleagueMap.get(interMap
						.get("CoffeeMachine")))).StartCoffee();
				((TV) (colleagueMap.get(interMap.get("TV")))).StartTv();
			} else if (stateChange == 1) {
				((TV) (colleagueMap.get(interMap.get("TV")))).StopTv();
			}

		} else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
			((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
					.UpCurtains();

		} else if (colleagueMap.get(colleagueName) instanceof TV) {//如果TV发现消息

		} else if (colleagueMap.get(colleagueName) instanceof Curtains) {
			//如果是以窗帘发出的消息,这里处理...
		}
	}

	@Override
	public void SendMessage() {
		// TODO Auto-generated method stub
	}
}

//具体的同事类
public class Alarm extends Colleague {

	//构造器
	public Alarm(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		//在创建Alarm 同事对象时,将自己放入到ConcreteMediator 对象中[集合]
		mediator.Register(name, this);
	}

	public void SendAlarm(int stateChange) {
		SendMessage(stateChange);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		//调用的中介者对象的getMessage
		this.GetMediator().GetMessage(stateChange, this.name);
	}
}

public class CoffeeMachine extends Colleague {

	public CoffeeMachine(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void StartCoffee() {
		System.out.println("It's time to startcoffee!");
	}

	public void FinishCoffee() {

		System.out.println("After 5 minutes!");
		System.out.println("Coffee is ok!");
		SendMessage(0);
	}
}

public class Curtains extends Colleague {

	public Curtains(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void UpCurtains() {
		System.out.println("I am holding Up Curtains!");
	}
}

public class TV extends Colleague {

	public TV(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void StartTv() {
		// TODO Auto-generated method stub
		System.out.println("It's time to StartTv!");
	}

	public void StopTv() {
		// TODO Auto-generated method stub
		System.out.println("StopTv!");
	}
}

	public static void main(String[] args) {
		//创建一个中介者对象
		Mediator mediator = new ConcreteMediator();
		
		//创建Alarm 并且加入到  ConcreteMediator 对象的HashMap
		Alarm alarm = new Alarm(mediator, "alarm");
		
		//创建了CoffeeMachine 对象,并  且加入到  ConcreteMediator 对象的HashMap
		CoffeeMachine coffeeMachine = new CoffeeMachine(mediator,
				"coffeeMachine");
		
		//创建 Curtains , 并  且加入到  ConcreteMediator 对象的HashMap
		Curtains curtains = new Curtains(mediator, "curtains");
		TV tV = new TV(mediator, "TV");
		
		//让闹钟发出消息
		alarm.SendAlarm(0);
		coffeeMachine.FinishCoffee();
		alarm.SendAlarm(1);
	}

运行结果:

注意细节

  1. 多个类相互耦合,会形成网状结构,使用中介者模式将网状结构分离成星型结构,进行解耦。
  2. 减少类间依赖,降低了耦合,符合迪米特原则。
  3. 中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响。
  4. 如果设计不当,中介者对象本身变得过于复杂,这点在使用时,特别注意。
相关推荐
HalvmånEver1 天前
7.高并发内存池大页内存申请释放以及使用定长内存池脱离new
java·spring boot·spring
凤山老林1 天前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
赶路人儿1 天前
UTC时间和时间戳介绍
java·开发语言
dreamread1 天前
【SpringBoot整合系列】SpringBoot3.x整合Swagger
java·spring boot·后端
6+h1 天前
【java】基本数据类型与包装类:拆箱装箱机制
java·开发语言·python
一直都在5721 天前
Spring面经
java·后端·spring
xiaoye37081 天前
如何在Spring中使用注解配置Bean的生命周期回调方法?
java·spring
闻哥1 天前
深入Redis的RDB和AOF两种持久化方式以及AOF重写机制的分析
java·数据库·spring boot·redis·spring·缓存·面试
犬小哈1 天前
面试官:设计模式的 7 大基本原则有哪些?
设计模式
jgyzl1 天前
2026.3.12 常见的缓存读写策略
java·后端·spring