仲裁者模式(只有一个仲裁者)
用处
组员向仲裁者报告,仲裁者向组员下达指令。避免互相指挥,意见难以统一导致工作进度滞后。
角色
- Mediator(仲裁者)
该角色负责定义与Colleague角色进行通信和做出决定的方法API。 - ConcreteMediator(具体的仲裁者)
该角色负责实现Mediator角色的方法API,负责实际做出决定。 - Colleague(同事)
该角色负责 定义与Mediator角色进行通信的方法API。 - ConcreteColleague(具体的同事)
改进角色负责实现Colleague角色的方法(API)。
类图
由类图可以看出
- ConcreteMediator类中聚合了ConcreteColleague类,而Colleague类中聚合了Mediator类,因此Mediator与Colleague是双向交互的关系。
举例
public class Main {
public static void main(String[] args) {
new LoginFrame("Mediator Sample");
}
}
//Mediator角色
interface Mediator{
void createColleagues();
void colleagueChanged();
}
//Colleague角色
interface Colleague{
void setMediator(Mediator mediator);
void setColleagueEnabled(boolean enabled);
}
//ConcreteColleague角色
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){ //Mediator下达启用/禁用指示
setEnabled(enabled);
}
}
//ConcreteColleague角色
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.lightGray);
}
public void textValueChanged(TextEvent e){//当文字发生变化时通知Mediator
mediator.colleagueChanged();
}
}
//ConcreteColleague角色
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();
}
}
//ConcreteMediator角色
class LoginFrame extends Frame implements ActionListener,Mediator{
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
private ColleagueCheckBox checkGuest;
private ColleagueCheckBox checkLogin;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
//构造函数
//生成并配置各个Colleague后,显示对话框
public LoginFrame(String 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);
}
public void colleagueChanged(){
if(checkGuest.getState()){
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(true);
}else{
textUser.setColleagueEnabled(true);
userpassChanged();
}
}
//当textUser或textPass文本输入框中文字发生改变时
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);
textPass.setColleagueEnabled(false);
}
}
public void actionPerformed(ActionEvent e){
System.out.println(e.toString());
System.exit(0);
}
可以看出
- ConcerteMediator与ConcreteColleague之间是交互的关系,ConcreteColleague中的方法用到了ConcreteMediator(例如itemStateChanged方法),而ConcreteMediator的方法中也用到了ConcreteColleague(例如colleagueChanged方法)。
- ConcreteMediator对ConcreteColleague进行统一指挥(例如colleagueChanged方法,userpassChanged方法)
总结
- 不符合开闭原则,新增ConcreteColleague类需要修改ConcreteMediator类。
- 外观模式中,Facade角色单方面使用其他角色来提供对外接口API,是单向的,而仲裁者模式中,Mediator角色与Colleague角色进行交互,是双向的。
- 仲裁者模式不让互相关联的对象之间直接通信,而是让他们向仲裁者进行报告,由仲裁者统一下达指示。