请大家想象一下,如果你身处在一个管理制度不完善的小公司开发项目。小组中有10个成员协同工作,意见很难统一,总是相互指挥,导致工作制度始终滞后。不仅如此,他们还很在乎细节,总结经常为此争执不下。这时候其实就需要一个领导站出来进行管理,:“各位,请大家将各自情况汇报给我,我负责仲裁”,领导从整个团队进行思考然后下达命令。这样当小组组员之间存在争议时候就不在相互争执,而是向上汇报,有仲裁者负责统一大家意见!
最后整个团队交流过程就变成了:“组员向仲裁者汇报,仲裁者将组员下达命令”。组员之间不在相互询问和相互指导。
本节我们将要学习中介者或者仲裁者模式。一方面当发送麻烦时候通知仲裁者;当发生涉及全部组员的事情时候也向仲裁者汇报,。当仲裁者下达命令时候组员立即执行。团队组员之间不在进行沟通并私自决定,而是任何事情都有仲裁者仲裁。另一方面,仲裁者站在整个团队的角度对组员汇报的事情做出决定。这就是中介者模式!
在中介者模式中,仲裁者被称为Mediator,各个组员称之为Colleague(同事的意思)
接下来以一个GUI程序进行演示中介者模式,此处GUI不是我们的重点,我们只关注业务。例如有一个登录对话框如图所示:
当选择游客登录时候,用户名,密码对话框都不可用,OK和Cancel按钮可用。
当选择Login时候,用户名可用,没有输入密码时候密码对话框不可用,当用户名密码都输入之后OK按钮可用
通过上面的业务来模拟演示中介者模式,在这里这些控件(按钮,复选框,文本框)就相当于是Colleague ,像这种调整各个控件之间的关系时候,就需要使用中介者模式了。
即不让各个对象之间相互通信,而是增加一个仲裁者对象,让他们与仲裁者相互通信。然后,将控制显示的逻辑处理交给仲裁者负责。
源码以及类的职责:
Mediator 仲裁者接口
Colleague 组员接口
ColleagueButton 实现组员接口的按钮
ColleagueCheckbox 实现组员接口的复选框
ColleagueTextField 实现组员接口的文本框
LoginFrame 登录对话框的类,实现了仲裁者接口
Main 测试程序的类
示例程序类图:
后期补上
代码程序:
public interface Mediator {
public abstract void createColleagues();
public abstract void colleagueChanged();
}
public interface Colleague {
public abstract void setMediator(Mediator mediator);
public abstract void setColleagueEnabled(boolean enabled);
}
import java.awt.Button;
public class ColleagueButton extends Button implements Colleague {
private Mediator mediator;
public ColleagueButton(String caption) {
super(caption);
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
}
}
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {
private Mediator mediator;
public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) {
super(caption, group, state);
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
}
public void itemStateChanged(ItemEvent e) {
mediator.colleagueChanged();
}
}
import java.awt.TextField;
import java.awt.Color;
import java.awt.event.TextListener;
import java.awt.event.TextEvent;
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) {
setEnabled(enabled);
setBackground(enabled ? Color.white : Color.lightGray);
}
public void textValueChanged(TextEvent e) {
mediator.colleagueChanged();
}
}
import java.awt.Frame;
import java.awt.Label;
import java.awt.Color;
import java.awt.CheckboxGroup;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class LoginFrame extends Frame implements ActionListener, Mediator {
private ColleagueCheckbox checkGuest;
private ColleagueCheckbox checkLogin;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
// 构造函数。
// 生成并配置各个Colleague后,显示对话框。
public LoginFrame(String title) {
super(title);
setBackground(Color.lightGray);
// 使用布局管理器生成4×2窗格
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 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);
}
// 接收来自于Colleage的通知然后判断各Colleage的启用/禁用状态。
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文本输入框中的文字发生变化时
// 判断各Colleage的启用/禁用状态
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);
}
}
import java.awt.*;
import java.awt.event.*;
public class Main {
static public void main(String args[]) {
new LoginFrame("Mediator Sample");
}
}
总结:
总裁者模式就是将组员的复杂的关系交给统一的仲裁者管理。
仲裁者中设计的角色:
仲裁者、具体仲裁者( Mediator、LoginFrame)
同事,具体的同事(Colleague、ColleagueButton等 )
中介者模式的类图:
后期补上
源码代码地址:http://Git.oschina.NET/leodaxin/javapattern