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) { // 保存 Mediator
this.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) { // 当文字发生变化时,通知 Mediator
mediator.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));
// 生成各个 Colleague
createColleagues();
// 配置
add(checkGuest);
add(checkLogin);
add(new Label("Username:"));
add(textUser);
add(new Label("Password:"));
add(textPass);
add(buttonOk);
add(buttonCancel);
// 设置初始化应用 禁用状态
colleagueChanged();
// 显示
pack();
show();
}
// 生成各个 Colleague
public 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");
// 设置 Mediator
checkGuest.setMediator(this);
checkLogin.setMediator(this);
textUser.setMediator(this);
textPass.setMediator(this);
buttonOk.setMediator(this);
buttonCancel.setMediator(this);
// 设置 Listener
checkGuest.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 mode
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(true);
} else { // Login mode
textUser.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 角色进行通信