背景
Mediator 是仲裁者,中介者的意思,一方面,当组员发生麻烦事时,通知仲裁者,发生涉及全体组员的事情时也通知仲裁者。当仲裁者下达命令时,组员会立即执行。组员向仲裁者报告,仲裁者向组员下达命令。
登场角色
Mediator 仲裁者 中介者
定义与 Colleague 角色 进行通信和做出决定的接口
ConcreteMediator 具体的仲裁者 中介者
实现 Mediator 角色中的接口
Colleague 同事
定义与 Mediator 角色进行通信的接口
ConcreteColleague 具体的同事
实现 Colleague 角色的接口
类图
示例代码
以一个实现一个登录框为例,具有以下的功能:
- 选择游客登录,禁用用户名和密码的输入框
- 选择用户登录,启用用户名和密码的输入框
- 如果用户名输入框的文本长度大于1,则启用密码框
- 如果密码输入框的文本长度大于1,则启用确认按钮
- OK按钮只有 用户名和密码输入框中文本长度均大于1时才能启用
- Cancle 按钮任何时候均能启用
Colleague
public interface Colleague {
// 设置仲裁者
void setMediator(Mediator mediator);
// 告知组员仲裁者所下达的命令,即仲裁者改变组员的状态
void setColleagueEnabled(boolean enabled);
}
ColleagueButton
public class ColleagueButton extends Button implements Colleague {
private Mediator mediator;
public ColleagueButton(String label) throws HeadlessException {
super(label);
}
@Override
public void setMediator(Mediator mediator) { // 保存 mediator
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) { // mediator 下达指令,组员改变状态
setEnabled(enabled);
}
}
ColleagueTextField
public class ColleagueTextField extends TextField implements Colleague, TextListener {
private Mediator mediator;
public ColleagueTextField(String text, int columns) throws HeadlessException {
super(text, columns);
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
setBackground(enabled ? Color.WHITE : Color.lightGray);
}
@Override
public void textValueChanged(TextEvent e) { // 告知mediator 自己的状态已经改变
mediator.colleagueChanged();
}
}
ColleagueCheckBox
public class ColleagueCheckBox extends Checkbox implements ItemListener, Colleague {
private Mediator mediator;
public ColleagueCheckBox(String label, CheckboxGroup group, boolean state) throws HeadlessException {
super(label, group, state);
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) { // 让仲裁者改变自己的状态
setEnabled(enabled);
}
@Override
public void itemStateChanged(ItemEvent e) { // 告知仲裁者自己的状态发生变化
mediator.colleagueChanged();
}
}
Mediator
public interface Mediator {
// 创建组员
void createColleagues();
// 组员向仲裁者报告,自己的状态发生了改变
void colleagueChanged();
}
LoginFrame
public class LoginFrame extends Frame implements Mediator, ActionListener {
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
private ColleagueCheckBox checkLogin;
private ColleagueCheckBox checkGuest;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
public LoginFrame(String title) throws HeadlessException {
super(title);
setBackground(Color.lightGray);
setLayout(new GridLayout(4, 2));
// 创建对象
createColleagues();
add(checkGuest);
add(checkLogin);
add(new Label("Username:"));
add(textUser);
add(new Label("Password:"));
add(textPass);
add(buttonOk);
add(buttonCancel);
// 设置初始的状态
colleagueChanged();
// 显示
pack();
show();
}
@Override
public void createColleagues() {
CheckboxGroup g = new CheckboxGroup();
checkGuest = new ColleagueCheckBox("Guest", g, true);
checkLogin = new ColleagueCheckBox("Login", g, false);
textUser = new ColleagueTextField("", 10);
textPass = new ColleagueTextField("", 10);
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);
}
@Override
public void colleagueChanged() {
if (checkGuest.getState()) {
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(true);
} else {
textUser.setColleagueEnabled(true);
userPassChanged();
}
}
private void userPassChanged() {
if (textUser.getText().length() > 0) {
textPass.setColleagueEnabled(true);
if (textPass.getText().length() > 0) {
buttonOk.setColleagueEnabled(true);
} else {
buttonOk.setColleagueEnabled(false);
}
} else {
buttonOk.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
}
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
}
}
功能分析
- 将逻辑处理集中在一个类中,其他类负责调用该方法,可以减少bug查找的时间,只需要查找 Mediator 类中的方法即可,避免将逻辑处理分散到其他类上;
- ConcreteColleague 角色可以复用,但 ConcreteMediator 类很难复用,因为ConcreteMediator类依赖于特定的应用程序,依赖于特定的逻辑实现;