1、引入
在工作中,往往遇到组员们各执己见的情况,或许他们各有其道理,但是如果都坚持自己观点互不退让,往往会降低工作效率乃至影响项目。此时,需要一位仲裁者出现,所有的情况告知仲裁者,让仲裁者统一决定,这样可以让使得工作井井有条。
Mediator模式便是则一现实案例在软件中的应用,对于发生过来的请求,统一交给仲裁者处理。
2、示例
实现一个登录界面,可以以游客或是会员身份进入,游客界面密码和账号选项不可用,会员界面必须填写账号和密码后才可以进入。
2.1、仲裁者接口
所有仲裁者的统一接口:
public interface Mediator {
public abstract void createColleagues();
public abstract void colleagueChanged();
}
2.2、各种交互项
2.2.1、统一的向仲裁者报告的接口
public interface Colleague {
public abstract void setMediator(Mediator mediator);
public abstract void setColleagueEnabled(Boolean enabled);
}
2.2.2、按钮类
public class ColleagueButton extends Button implements Colleague {
private Mediator mediator;
public ColleagueButton(String caption) {
super(caption);
}
@Override
public void setMediator(Mediator mediator) {
this.mediator=mediator;
}
@Override
public void setColleagueEnabled(Boolean enabled) {
setEnabled(enabled);
}
}
2.2.2、选项类
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);
}
public void itemStateChanged(ItemEvent e) {
mediator.colleagueChanged();
}
}
2.2.3、文本框类
public class ColleagueTextField extends TextField implements TextListener, Colleague {
private Mediator mediator;
public ColleagueTextField(String text, int columns) {
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);
}
public void textValueChanged(TextEvent e) {
mediator.colleagueChanged();
}
}
2.3、仲裁者实现之LoginFrame
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;
//构建窗口,可以不用在意具体细节,了解即可
public LoginFrame(String title) throws HeadlessException {
super(title);
setBackground(Color.lightGray);
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();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
}
@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);
//配置监听器
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 {
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(false);
}
}
}
3、tips
- 在各个交互项中本可以实现对用户操作的反应,但在这里统一交给仲裁者处理,实现了解耦:当需要更改交互逻辑时,只需要更改仲裁者即可。
- 在许多网页以及客户端制作中,都有着对仲裁者模式的广泛应用。