Author:Gorit
Date:2021年11月21日
Refer:《图解设计模式》
Website:CodingGorit 的小站
16.1 Mediator 模式
“Mediator”意思指的是 “仲裁者”、“中介者”
一方面,当发生麻烦事情的时候,通知仲裁者
另一方面,当发生涉及全体组员的事情时,也通知仲裁者。
当仲裁者下达指示时,组员立刻执行。团队组员之间不再互相沟通并私自做出决定,而是发生任何事情都要向仲裁者汇报。
另外仲裁者站在整个团队的角度上对组员上报的事情做出决定,这就是 Mediator 模式。
16.2 示例程序
| 类名 | 说明 |
|---|---|
| Mediator | 定义“仲裁者”的接口(API) |
| Colleague | 定义“组员”的接口(API) |
| ColleagueButton | 表示按钮的类,它实现了 Colleague 接口 |
| ColleagueTextField | 表示文本输入框的类。它实现了 Colleague 接口 |
| ColleagueRadioBox | 表示勾选框(单选框),实现 Colleague 接口 |
| LoginFrame | 表示登录对话框的类 |
| Main | 测试程序行为的类 |
Mediator接口
package Mediator;/*** @Author Gorit* @Date 2021/11/21* 仲裁者接口**/public interface Mediator {public abstract void createColleagues(); // 生成 Mediator 要管理的成员public abstract void colleagueChanged(); // 该方法会被各个 Colleague 组员调用。它的作用是让组员可以向仲裁者汇报}
Colleague 接口
package Mediator;/*** @Author Gorit* @Date 2021/11/21* 仲裁者接口**/public interface Mediator {public abstract void createColleagues(); // 生成 Mediator 要管理的成员public abstract void colleagueChanged(); // 该方法会被各个 Colleague 组员调用。它的作用是让组员可以向仲裁者汇报}
ColleagueButton
package Mediator;import java.awt.*;/*** @Author Gorit* @Date 2021/11/21* 与 LoginFrame 协作**/public class ColleagueButton extends Button implements Colleague {private Mediator mediator;public ColleagueButton(String caption) {super(caption);}public void setMediator(Mediator mediator) { // 保存 Mediatorthis.mediator = mediator;}public void setColleagueEnabled(boolean enabled) { // Mediator 下达启用, 禁用指示setEnabled(enabled);}}
ColleagueTextField
package Mediator;import java.awt.*;import java.awt.event.TextEvent;import java.awt.event.TextListener;/*** @Author Gorit* @Date 2021/11/21**/public class ColleagueTextField extends TextField implements TextListener, Colleague {private Mediator mediator;public ColleagueTextField(String text, int columns) { // 构造函数super(text, columns);}public void setMediator(Mediator mediator) {this.mediator = mediator;}public void setColleagueEnabled(boolean enabled) { // Mediator 下达启用,禁用指令setEnabled(enabled);setBackground(enabled ? Color.WHITE : Color.LIGHT_GRAY);}public void textValueChanged(TextEvent e) { // 当文字发生变化时,通知 Mediatormediator.colleagueChanged();}}
ColleagueRadioBox
package Mediator;import java.awt.*;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;/*** @Author Gorit* @Date 2021/11/21**/public class ColleagueRadioBox extends Checkbox implements ItemListener,Colleague {private Mediator mediator;public ColleagueRadioBox(String label, CheckboxGroup group, boolean state) {super(label, group, state);}public void setMediator(Mediator mediator) {this.mediator = mediator;}public void setColleagueEnabled(boolean enabled) {setEnabled(enabled);}public void itemStateChanged(ItemEvent e) {mediator.colleagueChanged();}}
LoginFrame
package Mediator;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;/*** @Author Gorit* @Date 2021/11/21* 仲裁者代码**/public class LoginFrame extends Frame implements ActionListener, Mediator {private ColleagueRadioBox checkGuest;private ColleagueRadioBox checkLogin;private ColleagueTextField textUser;private ColleagueTextField textPass;private ColleagueButton buttonOk;private ColleagueButton buttonCancel;/*** 设置背景色* 设置布局管理器 (4行 2列)* 调用 createColleagues 方法生成 Colleagues* 设置 Colleague* 设置初始状态* 显示* @param title*/public LoginFrame(String title) {super(title);setBackground(Color.lightGray);// 使用布局管理器生成 4x2的窗格setLayout(new GridLayout(4, 2));// 生成各个 ColleaguecreateColleagues();// 配置add(checkGuest);add(checkLogin);add(new Label("Username:"));add(textUser);add(new Label("Password:"));add(textPass);add(buttonOk);add(buttonCancel);// 设置初始化应用 禁用状态colleagueChanged();// 显示pack();show();}// 生成各个 Colleaguepublic void createColleagues() {// 生成CheckboxGroup q = new CheckboxGroup();checkGuest = new ColleagueRadioBox("Guest", q, true);checkLogin = new ColleagueRadioBox("Login", q, false);textUser = new ColleagueTextField("", 16);textPass = new ColleagueTextField("", 16);textPass.setEchoChar('*');buttonOk = new ColleagueButton("OK");buttonCancel = new ColleagueButton("Cancel");// 设置 MediatorcheckGuest.setMediator(this);checkLogin.setMediator(this);textUser.setMediator(this);textPass.setMediator(this);buttonOk.setMediator(this);buttonCancel.setMediator(this);// 设置 ListenercheckGuest.addItemListener(checkGuest);checkLogin.addItemListener(checkLogin);textUser.addTextListener(textUser);textPass.addTextListener(textPass);buttonOk.addActionListener(this);buttonCancel.addActionListener(this);}// 接收来自 Colleague 的通知然后判断各 Colleague 的启用 / 禁用。 简单的登录框逻辑转换public void colleagueChanged() {if (checkGuest.getState()) { // Guest modetextUser.setColleagueEnabled(false);textPass.setColleagueEnabled(false);buttonOk.setColleagueEnabled(true);} else { // Login modetextUser.setColleagueEnabled(true);userpassChanged();}}// 当 textUser 或 textPass 文本输入框中的文字发生变化时// 判断各 Colleague 的启用 | 禁用private void userpassChanged() {if (textUser.getText().length() > 0) {textPass.setColleagueEnabled(true);if (textPass.getText().length() > 0) {buttonOk.setColleagueEnabled(true);} else {buttonOk.setColleagueEnabled(false);}} else {textPass.setColleagueEnabled(false);buttonOk.setColleagueEnabled(false);}}public void actionPerformed(ActionEvent e) {System.out.println(e.toString());System.exit(0);}}
Main
package Mediator;/*** @Author Gorit* @Date 2021/11/21**/public class Main {static public void main(String[] args) {new LoginFrame("Mediator Sample");}}
16.3 Mediator 模式中登场的角色
一、Mediator(仲裁者、中介者)
Mediator 角色负责定义与 Colleague 角色进行通信和做出决定的接口(API)。在示例程序中,由 Mediator 接口扮演此角色。
二、ConcreateMediator(具体的仲裁者,中介者)
ConcreateMediator 负责实现 Mediator 接口,示例程序中由 LoginFrame 扮演此角色。
三、Colleague 同事
Colleague 角色负责定义与 Mediator 角色进行通信的接口(API),示例程序中由 Colleague接口担任此角色
四、ConcreateColleague
ColleagueButton、ColleagueRadioBox、ColleagueTextField 扮演此角色。
16.4 相关设计模式
一、Facade 模式
在 Mediator 模式中,Mediator 角色与 Colleague 角色进行交互
因此说 Mediator 是双向的,Facade 角色单方面的使用其他角色提供的接口(API),因此是单向的
二、Observer 模式
有时会使用 Observer 模式来实现,Mediator 和 Colleague 角色进行通信
