标签:
该如何来简化这种多个对象之间的交互呢?
中介者模式的定义:用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立改变它们之间的交互。
Mediator:中介者接口,在里面定义各个同事之间交互需要的方法,可以是公共的通信方法,比如changed方法,大家都用,也可以是小范围的交互方法
ConcreteMediator:具体中介者实现对象,它需要了解并维护各个同事对象,并负责协调各同事对象的交互关系
Colleague:同事类的定义,通常实现为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能
ConcreteColleague:具体的同事类,实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者负责与其他同事交互
代码:
/**
* 同事类的抽象父类
*/
public abstract class Colleague {
/**
* 持有中介者对象,每一个同事类都知道它的中介者对象
*/
private Mediator mediator;
/**
* 构造方法,传入中介者对象
* @param mediator 中介者对象
*/
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
/**
* 获取当前同事类对应的中介者对象
* @return 对应的中介者对象
*/
public Mediator getMediator() {
return mediator;
}
}
/**
* 光驱类,一个同事类
*/
public class CDDriver extends Colleague{
public CDDriver(Mediator mediator) {
super(mediator);
}
/**
* 光驱读取出来的数据
*/
private String data = "";
/**
* 获取光驱读取出来的数据
* @return 光驱读取出来的数据
*/
public String getData(){
return this.data;
}
/**
* 读取光盘
*/
public void readCD(){
//逗号前是视频显示的数据,逗号后是声音
this.data = "设计模式,值得好好研究";
//通知主板,自己的状态发生了改变
this.getMediator().changed(this);
}
}
/**
* CPU类,一个同事类
*/
public class CPU extends Colleague{
public CPU(Mediator mediator) {
super(mediator);
}
/**
* 分解出来的视频数据
*/
private String videoData = "";
/**
* 分解出来的声音数据
*/
private String soundData = "";
/**
* 获取分解出来的视频数据
* @return 分解出来的视频数据
*/
public String getVideoData() {
return videoData;
}
/**
* 获取分解出来的声音数据
* @return 分解出来的声音数据
*/
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 interface Mediator {
/**
* 同事对象在自身改变的时候来通知中介者的方法,
* 让中介者去负责相应的与其他同事对象的交互
* @param colleague 同事对象自身,好让中介者对象通过对象实例
* 去获取同事对象的状态
*/
public void changed(Colleague colleague);
}
/**
* 主板类,实现中介者接口
*/
public class MotherBoard implements Mediator{
/**
* 需要知道要交互的同事类――光驱类
*/
private CDDriver cdDriver = null;
/**
* 需要知道要交互的同事类――CPU类
*/
private CPU cpu = null;
/**
* 需要知道要交互的同事类――显卡类
*/
private VideoCard videoCard = null;
/**
* 需要知道要交互的同事类――声卡类
*/
private SoundCard soundCard = null;
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;
}
public void changed(Colleague colleague) {
if(colleague == cdDriver){
//表示光驱读取数据了
this.opeCDDriverReadData((CDDriver)colleague);
}else if(colleague == cpu){
//表示CPU处理完了
this.opeCPU((CPU)colleague);
}
}
/**
* 处理光驱读取数据过后与其他对象的交互
* @param cd 光驱同事对象
*/
private void opeCDDriverReadData(CDDriver cd){
//1:先获取光驱读取的数据
String data = cd.getData();
//2:把这些数据传递给CPU进行处理
this.cpu.executeData(data);
}
/**
* 处理CPU处理完数据后与其他对象的交互
* @param cpu CPU同事类
*/
private void opeCPU(CPU cpu){
//1:先获取CPU处理过后的数据
String videoData = cpu.getVideoData();
String soundData = cpu.getSoundData();
//2:把这些数据传递给显卡和声卡展示出来
this.videoCard.showData(videoData);
this.soundCard.soundData(soundData);
}
}
public class Client {
public static void main(String[] args) {
//1:创建中介者――主板对象
MotherBoard mediator = new MotherBoard();
//2:创建同事类
CDDriver cd = new CDDriver(mediator);
CPU cpu = new CPU(mediator);
VideoCard vc = new VideoCard(mediator);
SoundCard sc = new SoundCard(mediator);
//3:让中介者知道所有的同事
mediator.setCdDriver(cd);
mediator.setCpu(cpu);
mediator.setVideoCard(vc);
mediator.setSoundCard(sc);
//4:开始看电影,把光盘放入光驱,光驱开始读盘
cd.readCD();
}
}
1) 中介者模式的功能非常简单,就是封装对象之间的交互。
中介者对象和同事对象之间是相互依赖的。
2) 中介者模式的本质:封装交互
3) 广义中介者模式
1. 通常会去掉同事对象的父类
2. 通常不定义Mediator接口,把具体的中介者对象实现成为单例
3. 同事对象不再持有中介者,中介者也不再持有同事对象。
/**
* 部门类
*/
public class Dep {
/**
* 描述部门编号
*/
private String depId;
/**
* 描述部门名称
*/
private String depName;
public String getDepId() {
return depId;
}
public void setDepId(String depId) {
this.depId = depId;
}
public String getDepName() {
return depName;
}
public void setDepName(String depName) {
this.depName = depName;
}
/**
* 撤销部门
* @return 是否撤销成功
*/
public boolean deleteDep(){
//1:要先通过中介者去清除掉所有与这个部门相关的部门和人员的关系
DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
mediator.deleteDep(depId);
//2:然后才能真的清除掉这个部门
//请注意在实际开发中,这些业务功能可能会做到业务层去,
//而且实际开发中对于已经使用的业务数据通常是不会被删除的,
//而是会被做为历史数据保留
return true;
}
}
/**
* 人员类
*/
public class User{
/**
* 人员编号
*/
private String userId;
/**
* 人员名称
*/
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
/**
* 人员离职
* @return 是否处理成功
*/
public boolean dimission(){
//1:要先通过中介者去清除掉所有与这个人员相关的部门和人员的关系
DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
mediator.deleteUser(userId);
//2:然后才能真的清除掉这个人员
//请注意,实际开发中,人员离职,是不会真的删除人员记录的,
//通常是把人员记录的状态或者是删除标记设置成已删除,
//只是不再参加新的业务,但是已经发生的业务记录是不会被清除掉的
return true;
}
}
/**
* 描述部门和人员关系的类
*/
public class DepUserModel {
/**
* 用于部门和人员关系的编号,用做主键
*/
private String depUserId;
/**
* 部门的编号
*/
private String depId;
/**
* 人员的编号
*/
private String userId;
public String getDepUserId() {
return depUserId;
}
public void setDepUserId(String depUserId) {
this.depUserId = depUserId;
}
public String getDepId() {
return depId;
}
public void setDepId(String depId) {
this.depId = depId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
/**
* 实现部门和人员交互的中介者实现类
* 说明:为了演示的简洁性,只示例实现撤销部门和人员离职的功能
*/
public class DepUserMediatorImpl {
private static DepUserMediatorImpl mediator = new DepUserMediatorImpl();
private DepUserMediatorImpl(){
//调用初始化测试数据的功能
initTestData();
}
public static DepUserMediatorImpl getInstance() {
return mediator;
}
/**
* 测试用,记录部门和人员的关系
*/
private 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) {
//请注意:为了演示简单,部门撤销后,原部门的人员怎么处理等后续业务处理,这里就不管了
//1:到记录部门和人员关系的集合里面,寻找跟这个部门相关的人员
//设置一个临时的集合,记录需要清除的关系对象
Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
for(DepUserModel du : depUserCol){
if(du.getDepId().equals(depId)){
//2:需要把这个相关的记录去掉,先记录下来
tempCol.add(du);
}
}
//3:从关系集合里面清除掉这些关系
depUserCol.removeAll(tempCol);
return true;
}
/**
* 完成因人员离职引起的与部门的交互
* @param userId 离职的人员的编号
* @return 是否正确处理了因人员离职引起的与部门的交互
*/
public boolean deleteUser(String userId) {
//1:到记录部门和人员关系的集合里面,寻找跟这个人员相关的部门
//设置一个临时的集合,记录需要清除的关系对象
Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
for(DepUserModel du : depUserCol){
if(du.getUserId().equals(userId)){
//2:需要把这个相关的记录去掉,先记录下来
tempCol.add(du);
}
}
//3:从关系集合里面清除掉这些关系
depUserCol.removeAll(tempCol);
return true;
}
/**
* 测试用,在内部打印显示一下一个部门下的所有人员
* @param dep 部门对象
*/
public void showDepUsers(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 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.showDepUsers(dep2);
//真正执行业务,人员离职
user.dimission();
//再次输出一下,看这个部门下都有哪些人员
System.out.println("人员离职后------------------");
mediator.showDepUsers(dep2);
}
}
标签:
原文地址:http://blog.csdn.net/jiangxishidayuan/article/details/51943131