Java 设计模式 之 中介者模式(Mediator)
中介者的功能非常简单,就是封装对象之间的交互。
如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把所有麻烦扔给它,只要在需要的时候通知中介者,其他的就让中介者去处理就可以了。
反过来,其他对象在操作时,可能会引起这个对象的变化,也可以这么做。最后对象之间就完全分离了,谁都不直接跟其他对象交互,那么相互之间的关系完全集中到中介者里面了,所有的对象都通过中介者进行通信,相互之间就不在有联系了,对象之间的耦合就松散了。
● 标准的中介者模式
① Mediator :中介者接口。在里面定义各个同事对象之间的交互对象,可以是公共的通信方法,比如changed 方法,大家都用,也可以是小范围的交互方法。
② ConcreteMediator :具体中介者实现对象。他需要维护各个同事对象之间的交互关系,比如下例中的MainBoard。
③ Colleague :同事类的定义,所有具体同事类的父类,通常实现成抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的功能。
④ ConcreteColleague :具体的同事类,实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者负责与其他的同事进行交互。

/**
* 中介者,定义各个同事对象的通信接口
* @author joe
*
*/
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知中介者的方法
* 让中介者去负责相应的与其他同事对象的交互
* @param colleague 同事对象自身,好让中介者对象通过对象实例
* 去获取同事对象的状态
*/
public void changed(Colleague colleague);
}
/**
* 主板类,实现中介者接口
*
*/
public class MainBoard implements Mediator {
private CDDriver cdDriver;
private CPU cpu;
private VideoCard videoCard;
private SoundCard soundCard;
@Override
public void changed(Colleague colleague) {
if(colleague == cdDriver){
//表示光驱读取了数据
this.operateCDDriverReadData((CDDriver)colleague);
}else if(colleague == cpu){
//表示CPU处理完数据
this.operateCPU((CPU)colleague);
}
}
public void setCdDriver(CDDriver cdDriver) {
this.cdDriver = cdDriver;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
/**
* 处理光驱读取数据后与其他对象的交互
* @param cd
*/
public void operateCDDriverReadData(CDDriver cd){
String data = cd.getData();
this.cpu.executeData(data);
}
/**
* 处理CPU处理完数据后与其他对象的交互
* @param cpu
*/
public void operateCPU(CPU cpu){
String videoData = cpu.getVideoData();
String soundData = cpu.getSoundData();
this.videoCard.showData(videoData);
this.soundCard.soundData(soundData);
}
}
/**
* 同事类的抽象父类
*
*/
public abstract class Colleague {
/**
* 持有中介者对象,每一个同事类都知道它的中介者对象
*/
private final Mediator mediator;
/**
* 构造方法,传入中介者对象
* @param mediator 中介者对象
*/
public Colleague(Mediator mediator){
this.mediator = mediator;
}
/**
* 获得当前同事类对应的中介者对象
* @return 对应的中介者对象
*/
public Mediator getMediator(){
return mediator;
}
}
/**
* 光驱类,一个同事类
*
*/
public class CDDriver extends Colleague {
/**
* 光盘数据
*/
private String data;
public CDDriver(Mediator mediator) {
super(mediator);
}
/**
* 获取光盘读取出来的数据
* @return 光盘数据
*/
public String getData() {
return data;
}
/**
* 读取光盘
*/
public void readCD(){
//逗号前是视频数据,逗号后是音频数据
this.data = "Video Data,Sound Data";
//通知主板,自己的状态发生了变化
this.getMediator().changed(this);
}
}
/**
* CPU 类,一个同事类
*
*/
public class CPU extends Colleague {
/**
* 视频数据
*/
private String videoData;
/**
* 音频数据
*/
private String soundData;
public CPU(Mediator mediator) {
super(mediator);
}
public String getVideoData() {
return videoData;
}
public String getSoundData() {
return soundData;
}
/**
* 处理数据,把数据分解成视频数据和音频数据
* @param data 被处理的数据
*/
public void executeData(String data){
//分解数据,前面是视频数据,后面是音频数据
String[] ss = data.split(",");
this.videoData = ss[0];
this.soundData = ss[1];
//通知主板,CPU的工作完成
this.getMediator().changed(this);
}
}
/**
* 声卡类,一个同事类
*
*/
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator){
super(mediator);
}
/**
* 发出声音
* @param data 音频数据
*/
public void soundData(String data){
System.out.println("画外音:" + data);
}
}
/**
* 显卡类,一个同事类
*
*/
public class VideoCard extends Colleague {
public VideoCard(Mediator mediator) {
super(mediator);
}
/**
* 显示视频数据
* @param data 被显示的数据
*/
public void showData(String data){
System.out.println("你正在观看的是:" + data);
}
}
public class Client {
public static void main(String[] args) {
MainBoard mediator = new MainBoard();
CDDriver cd = new CDDriver(mediator);
CPU cpu = new CPU(mediator);
VideoCard vc = new VideoCard(mediator);
SoundCard sc = new SoundCard(mediator);
mediator.setCdDriver(cd);
mediator.setCpu(cpu);
mediator.setVideoCard(vc);
mediator.setSoundCard(sc);
cd.readCD();
}
}
● 广义中介者
① 通常会去掉同事对象的父类,这样可以让任意的对象,只要需要相互交互,就可以成为同事。
② 同事不定义Mediator 接口,把具体的中介者实现成单例。
③ 同事对象不再持有中介者对象,而是在具体处理方法里面去创建,或者获取,或者从参数传入需要的同事对象。

/**
* 描述部门与人员关系的类
*
*/
public class DepUserModel {
private String depUserId;
private String depId;
private String userId;
//省略Setter 和 Getter
}
/**
* 实现部门和人员交互的中介者实现类
*
*/
public class DepUserMediatorImpl {
private static DepUserMediatorImpl mediator = new DepUserMediatorImpl();
private DepUserMediatorImpl(){
initTestData();
}
public static DepUserMediatorImpl getInstance(){
return mediator;
}
/**
* 记录部门和人员关系
*/
private final Collection<DepUserModel> depUserCol = new ArrayList<DepUserModel>();
/**
* 初始化测试数据
*/
private void initTestData(){
DepUserModel du1 = new DepUserModel();
du1.setDepUserId("du1");
du1.setDepId("d1");
du1.setUserId("u1");
depUserCol.add(du1);
DepUserModel du2 = new DepUserModel();
du2.setDepUserId("du2");
du2.setDepId("d1");
du2.setUserId("u2");
depUserCol.add(du2);
DepUserModel du3 = new DepUserModel();
du3.setDepUserId("du3");
du3.setDepId("d2");
du3.setUserId("u3");
depUserCol.add(du3);
DepUserModel du4 = new DepUserModel();
du4.setDepUserId("du4");
du4.setDepId("d2");
du4.setUserId("u4");
depUserCol.add(du4);
DepUserModel du5 = new DepUserModel();
du5.setDepUserId("du5");
du5.setDepId("d2");
du5.setUserId("u1");
depUserCol.add(du5);
}
/**
* 当部门被撤销时,应删去部门与该部门中人员的关系
* @param depId 被撤销部门的编号
* @return
*/
public boolean deleteDep(String depId){
Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
for(DepUserModel du : depUserCol){
if(du.getDepId().equals(depId)){
tempCol.add(du);
}
}
depUserCol.removeAll(tempCol);
return true;
}
/**
* 当人员离职时,应删去该人员与所在部门的关系
* @param userId 离职人员的编号
* @return
*/
public boolean deleteUser(String userId){
Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
for(DepUserModel du : depUserCol){
if(du.getUserId().equals(userId)){
tempCol.add(du);
}
}
depUserCol.removeAll(tempCol);
return true;
}
/**
* 显示部门中的所有人员
* @param dep 部门对象
*/
public void showDepUser(Dep dep){
for(DepUserModel du : depUserCol){
if(du.getDepId().equals(dep.getDepId())){
System.out.println("部门编号=" + dep.getDepId() + "下面拥有人员,其编号是:" + du.getUserId());
}
}
}
/**
* 显示人员所在的部门
* @param user 人员对象
*/
public void showUserDeps(User user){
for(DepUserModel du : depUserCol){
if(du.getUserId().equals(user.getUserId())){
System.out.println("人员编号=" + user.getUserId() + "属于部门编号是:" + du.getDepId());
}
}
}
/**
* 完成因人员调换部门引起的与部门的交互
* @param userId 被调换的人员的编号
* @param oldDepId 调换前的部门编号
* @param newDepId 调换后的部门编号
* @return
*/
public boolean changeDep(String userId, String oldDepId, String newDepId){
// 本示例就不是实现了
return false;
}
/**
* 因部门合并所引起的与人员的交互
* @param colDepIds 需要被合并的部门编号
* @param newDep 合并后部门的编号
* @return
*/
public boolean joinDep(Collection<String> colDepIds, Dep newDep){
// 本示例就不是实现了
return false;
}
}
public class User {
private String userId;
private String userName;
/**
* 人员离职
* @return
*/
public boolean dimission(){
DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
mediator.deleteUser(userId);
return true;
}
//省略Getter 和 Setter
}
/**
* 部门类
*
*/
public class Dep {
private String depId;
private String depName;
/**
* 撤销部门
* @return
*/
public boolean deleteDep(){
DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
mediator.deleteDep(depId);
return true;
}
}
public class Client {
public static void main(String[] args) {
DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
Dep dep = new Dep();
dep.setDepId("d1");
Dep dep2 = new Dep();
dep2.setDepId("d2");
User user = new User();
user.setUserId("u1");
System.out.println("撤销部门前----------------------------------------");
mediator.showUserDeps(user);
//撤销部门
dep.deleteDep();
System.out.println("撤销部门后----------------------------------------");
mediator.showUserDeps(user);
System.out.println("----------------------------------------");
System.out.println("人员离职前----------------------------------------");
mediator.showDepUser(dep2);
//人员离职
user.dimission();
System.out.println("人员离职后----------------------------------------");
mediator.showDepUser(dep2);
}
}
Java 设计模式 之 中介者模式(Mediator)的更多相关文章
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...
- 二十四种设计模式:中介者模式(Mediator Pattern)
中介者模式(Mediator Pattern) 介绍用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 示例有一个Messa ...
- 从中国加入WTO来看Java设计模式:中介者模式
目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...
- [设计模式] 17 中介者模式 Mediator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...
- Java 设计模式之中介者模式
本文继续23种设计模式系列之中介者模式. 定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 角色 抽象中介者: ...
- 设计模式之中介者模式(Mediator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程.它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
- 大熊君说说JS与设计模式之------中介者模式Mediator
一,总体概要 1,笔者浅谈 我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介.租房者并不关心他租谁的房.房东出租者也不关心他租给谁.因为有中介的存在 ...
随机推荐
- JAVA交换两个变量的值-(不使用第三变量)
以下方法的根本原理就是: 借助第三个变量 c = a; a = b; b = c; 运算符-不借助第三变量: a = a+b; b = a-b; a = a-b; 为运算符-不借助第三个变量: (此种 ...
- ubuntu16 sogou install
1,下载搜狗deb文件(ubuntu16不要参考搜狗旧的安装文档): http://pinyin.sogou.com/linux/ 2,双击sogoupinyin_2.1.0.0086_amd64.d ...
- TF随笔-7
求平均值的函数 reduce_mean axis为1表示求行 axis为0表示求列 >>> xxx=tf.constant([[1., 10.],[3.,30.]])>> ...
- [Python] print中的左右对齐问题
一.数值类型(int.float) # %d.%f是占位符>>> a = 3.1415926>>> print("%d"%a) #%d只 ...
- 使用tr1的bind函数模板
最近把公司的VS2008统一升级为SP1了,虽然还是有些跟不上时代,毕竟C++17标准都出了,但是,对于成熟的商业软件开发而言,追求更新的C++标准肯定不是正道.升级SP1的VS2008可以支持TR1 ...
- 【集成学习】 lightgbm原理
# lightgbm和xgboost对比: 模型精度:lightgbm≈xgboost 收敛速度:lightgbm>xgboost #
- 一个简单的程序,统计文本文档中的单词和汉字数,逆序排列(出现频率高的排在最前面)。python实现。
仅简单统计英文. from collections import Counter f = open('1') c = Counter() for line in f: g = (x for x in ...
- Mysql查询架构信息
今天想给整个数据库做初始化,也就是清空所有表,然后让索引归零,使用truncate table 就可以,但好多张表,怎么批量搞定呢? 有人说重建表吧,dump一下,然后再重建,但我还是想用trunca ...
- ZOJ3551Bloodsucker (数学期望)
In 0th day, there are n-1 people and 1 bloodsucker. Every day, two and only two of them meet. Nothin ...
- BZOJ1563 NOI2009 诗人小G【决策单调性优化DP】
LINK 因为是图片题就懒得挂了 简要题意:有n个串,拼接两个串需要加一个空格,给你l和p,问你拼接后每个串的总长减l的绝对值的p次方的最小值 首先打表发现一下这题是决策单调的对于所有数据都成立就当他 ...