Gof23种设计模式(18)——中介者模式(Mediator)

2020年8月14日10:23:07 评论 55

1 基础知识

1.1 标准定义

中介者(Mediator)模式标准定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

1.2 分析和说明

中介者(Mediator)模式,属于对象行为型模式。中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。中介者模式将多对多的相互作用转化为一对多的相互作用,将类与类之间的复杂的相互关系封装到一个中介者类中。中介者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。

中介者(Mediator)模式结构如图1所示,其角色包括抽象中介者(Mediator)角色、具体中介者(Concrete Mediator)角色、抽象同事类(Colleague)角色和具体同事类(Concrete Colleague)角色等。

Gof23种设计模式(18)——中介者模式(Mediator)

图1中介者模式结构

 抽象中介者(Mediator)角色:定义出同事对象到中介者对象的接口,其中主要的方法是一个(或者多个)事件方法。在有些情况下,这个抽象对象可以省略。一般而言,这个角色由一个抽象类或者接口实现。

 具体中介者(Concrete Mediator)角色:从抽象中介者继承而来,实现了抽象超类所声明的事件方法。具体中介者知晓所有的具体同事类,它从具体同事对象接收消息、向具体同事对象发出命令。一般而言,这个角色由一个具体类实现。

 抽象同事类(Colleague)角色:定义出中介者到同事对象的接口。同事对象只知道中介者而不知道其余的同事对象。一般而言,这个角色由一个抽象类或者对象实现。

 具体同事类(Concrete Colleague)角色:所有的具体同事类均从抽象同事类继承而来。每一个具体同事类都很清楚它自己在小范围的行为,而不知道它在大范围内的目的。在示意性的类图中,具体同事类是Colleague1和Colleague2。一般而言,这个角色由一个具体类实现。

2 应用场景举例

比如公司有很多项目,项目包括项目工作和项目人员。但有的时候,一些项目人员过多,一些项目人员过少。一些项目工作量大,一些项目工作量小,这就需要技术总监充当协调者,把一些项目的人员调到另一些项目上,或者把一些项目的工作安排到另外的项目中。规则中不允许项目经理之间自我调整,而必须要技术总监来调停,这就是中介者模式。用例图见图2。

Gof23种设计模式(18)——中介者模式(Mediator)

图2 中介者模式用例图

在这里可以把Mediator抽象类理解为抽象中介者(Mediator)角色。TechnicalDirector类理解为具体中介者(Concrete Mediator)角色。AbstractProject抽象类理解为抽象同事类(Colleague)角色。ProjectA类和ProjectB类是具体同事类(Concrete Colleague)角色。其实现类图如图3所示。TechnicalDirector类一方面继承Mediator抽象类,另一方面被AbstractProject抽象类关联。ProjectA类和ProjectB类继承AbstractProject抽象类,同时被TechnicalDirector类关联。

Gof23种设计模式(18)——中介者模式(Mediator)
图3 中介者模式类图

中介者模式实现顺序图见图4,实现顺序描述:
①基于TechnicalDirector类创建一个leader对象;
②基于ProjectA类创建一个projectA对象;
③基于ProjectB类创建一个projectB对象;
④调用leader对象setProjectA方法,把projectA对象赋值给leader对象。
⑤调用leader对象setProjectB方法,把projectB对象赋值给leader对象。
⑥调用leader对象changMember方法,实现projectA对象和projectB对象的人员调动;
⑦调用leader对象changTask方法,实现projectA对象和projectB对象的任务调动;
⑧调用projectA对象的showProjectContent方法,显示projectA内部人员和任务情况;
⑨调用projectB对象的showProjectContent方法,显示projectB内部人员和任务情况;

Gof23种设计模式(18)——中介者模式(Mediator)图4 中介者模式实现顺序图

leader对象就是一个中介者,projectA对象和projectB对象内部的人员和任务交换和协调,都通过leader对象的方法来实现。

3.Java的实现程序代码

Java程序实现主要包括AbstractProject抽象类文件,Mediator抽象类文件,TechnicalDirector类文件,ProjectA类文件,ProjectB类文件,Member类文件和Task类文件等7个文件。其关系如图3所示。下面分别列出这7个文件的程序代码,最后列出测试代码并显示输出结果。

AbstractProject抽象类程序代码清单01所示。

程序代码清单01

public abstract class AbstractProject {

	protected String projectName;
	protected TechnicalDirector leader;
	protected Map<String, Member> memberMap = new HashMap<String, Member>();
	protected Map<String, Task> taskMap = new HashMap<String, Task>();

	protected void initizeTask(Map<String, Task> map) {
		taskMap = map;
	}

	protected void initizeMember(Map<String, Member> map) {
		memberMap = map;
	}

	public void addMember(Member member) {
		memberMap.put(member.getMemberName(), member);
	}

	public void removeMember(Member member) {
		memberMap.remove(member.getMemberName());
	}

	public void addTask(Task task) {
		taskMap.put(task.getTaskName(), task);
	}

	public void reduceTask(Task task) {
		taskMap.remove(task.getTaskName());
	}

	public String getProjectName() {
		return projectName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public TechnicalDirector getLeader() {
		return leader;
	}

	public void setLeader(TechnicalDirector leader) {
		this.leader = leader;
	}

	public void showProjectContent() {

		System.out.println("显示" + getProjectName() + "项目成员和任务情况:");
		System.out.print("项目成员:");

		String memberName;
		Iterator it = memberMap.keySet().iterator();

		while (it.hasNext()) {
			memberName = (String) it.next();
			System.out.print(memberName + ";");
		}

		System.out.println();

		String taskName;

		System.out.print("项目任务:");

		it = taskMap.keySet().iterator();
		while (it.hasNext()) {
			taskName = (String) it.next();
			System.out.print(taskName + ";");
		}
		System.out.println();
	}
}

Mediator抽象类程序代码清单02所示。

程序代码清单02

public abstract class Mediator {

	public void changMember(AbstractProject project1, 
			AbstractProject project2, Member member) {
		project1.removeMember(member);
		project2.addMember(member);
	}

	public void changTask(AbstractProject project1, 
			AbstractProject project2, Task task) {
		project1.reduceTask(task);
		project2.addTask(task);
	}

	public void doCoordination() {
	}
}

TechnicalDirector继承Mediator抽象类,其程序代码清单03所示。

程序代码清单03

public class TechnicalDirector extends Mediator {

	private ProjectA projectA;
	private ProjectB projectB;
	private String directorName;

	public String getDirectorName() {
		return directorName;
	}

	public void setDirectorName(String directorName) {
		this.directorName = directorName;
	}

	public ProjectA getProjectA() {
		return projectA;
	}

	public void setProjectA(ProjectA projectA) {
		this.projectA = projectA;
	}

	public ProjectB getProjectB() {
		return projectB;
	}

	public void setProjectB(ProjectB projectB) {
		this.projectB = projectB;
	}

	public void doCoordination() {
	}
}

ProjectA类和ProjectB类继承AbstractProject抽象类,其程序代码清单04所示。

程序代码清单04

public class ProjectA extends AbstractProject {

	public ProjectA(Map<String, Member> members, Map<String, Task> tasks) {
		initizeMember(members);
		initizeTask(tasks);
		projectName = "ProjectA";
	}
}

public class ProjectB extends AbstractProject {

	public ProjectB(Map<String, Member> members, Map<String, Task> tasks) {
		initizeMember(members);
		initizeTask(tasks);
		projectName = "ProjectB";
	}
}

Member类和Task类程序代码清单05所示。

程序代码清单05

public class Member {

	private String memberName;

	public Member(String name) {
		setMemberName(name);
	}

	public String getMemberName() {
		return memberName;
	}

	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}

}

public class Task {

	private String taskName;

	public Task(String name) {
		setTaskName(name);
	}

	public String getTaskName() {
		return taskName;
	}

	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

}

中介者模式测试程序的代码清单06如下:

程序代码清单06

public class Client {

	public static void main(String[] args) {

		// 初始化项目人员和任务信息
		Member Programmer1 = new Member("程序员1");
		Member Programmer2 = new Member("程序员2");

		Member Designer1 = new Member("设计师1");
		Member Designer2 = new Member("设计师2");

		Task ProgramTask1 = new Task("编程工作1");
		Task ProgramTask2 = new Task("编程工作2");

		Task DesignTask1 = new Task("设计工作1");
		Task DesignTask2 = new Task("设计工作2");

		Map<String, Member> ProgrammerMap = new HashMap<String, Member>();
		ProgrammerMap.put(Programmer1.getMemberName(), Programmer1);
		ProgrammerMap.put(Programmer2.getMemberName(), Programmer2);

		Map<String, Member> DesignerMap = new HashMap<String, Member>();
		DesignerMap.put(Designer1.getMemberName(), Designer1);
		DesignerMap.put(Designer2.getMemberName(), Designer2);

		Map<String, Task> ProgramTaskMap = new HashMap<String, Task>();
		ProgramTaskMap.put(ProgramTask1.getTaskName(), ProgramTask1);
		ProgramTaskMap.put(ProgramTask2.getTaskName(), ProgramTask2);

		Map<String, Task> DesignTaskMap = new HashMap<String, Task>();
		DesignTaskMap.put(DesignTask1.getTaskName(), DesignTask1);
		DesignTaskMap.put(DesignTask2.getTaskName(), DesignTask2);

		ProjectA projectA = new ProjectA(ProgrammerMap, ProgramTaskMap);
		ProjectB projectB = new ProjectB(DesignerMap, DesignTaskMap);

		// 进行项目人员和工作的协调
		System.out.println("—————————协调前的情况—————————");
		projectA.showProjectContent();
		projectB.showProjectContent();

		TechnicalDirector leader = new TechnicalDirector();
		leader.setProjectA(projectA);
		leader.setProjectB(projectB);

		// 协调两个项目的人员
		leader.changMember(projectA, projectB, Programmer1);
		leader.changMember(projectB, projectA, Designer1);

		// 协调两个项目的任务
		leader.changTask(projectA, projectB, ProgramTask1);
		leader.changTask(projectB, projectA, DesignTask1);

		System.out.println("—————————协调后的情况—————————");
		projectA.showProjectContent();
		projectB.showProjectContent();
	}
}

中介者模式测试类输出结果如下所示:

—————————协调前的情况—————————
显示ProjectA项目成员和任务情况:
项目成员:程序员2;程序员1;
项目任务:编程工作1;编程工作2;
显示ProjectB项目成员和任务情况:
项目成员:设计师1;设计师2;
项目任务:设计工作2;设计工作1;

—————————协调后的情况—————————
显示ProjectA项目成员和任务情况:
项目成员:设计师1;程序员2;
项目任务:设计工作1;编程工作2;
显示ProjectB项目成员和任务情况:
项目成员:程序员1;设计师2;
项目任务:设计工作2;编程工作1;

参考链接

11种行为型模式

Gof23种设计模式(13)——解释器模式(Interpreter)
Gof23种设计模式(14)——模板方法模式(Template Method)
Gof23种设计模式(15)——责任链模式(Chain of Responsibility)
Gof23种设计模式(16)——命令模式(Command)
Gof23种设计模式(17)——迭代器模式(Iterator)
Gof23种设计模式(18)——中介者模式(Mediator)
Gof23种设计模式(19)——备忘录模式(Memento)
Gof23种设计模式(20)——观察者模式(Observer)
Gof23种设计模式(21)——状态模式(State)
Gof23种设计模式(22)——策略模式(Strategy)
Gof23种设计模式(23)——访问者模式(Visitor)
Gof23种设计模式 —— 行为型模式总结和比较

回到总目录Gof23种设计模式(全解析)

(转载自微信公众号:架构设计模式)

素课网
  • 本文由 发表于 2020年8月14日10:23:07
  • 转载请注明:https://www.suketech.com/9282.html
设计模式:面向对象设计的六大原则 - 总结 设计模式

设计模式:面向对象设计的六大原则 – 总结

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: