目录
1.Mediator模式
1.1 作用
当组员众多,交流混乱时,需要一个仲裁者,使整个团队的交流过程变为了组员向仲裁者(中介者)报告,仲裁者向组员下达指标,这就是Mediator模式。团队组员之间不再互相沟通并私自做出决定,而是发生任何事情都向仲裁者报告。
1.2 示例程序
实现一个对话框,条件为:
- 如果选择作为游客访问,那么禁用用户名输入框和密码输入框,使用户无法输入
- 如果选择作为用户登陆,那么启用用户名输入框和密码输入框,使用户可以输入
- 如果在用户名输入框中一个字符都没有输入,那么禁用密码输入框,使用户无法输入密码
- 如果在用户名输入框中输入了至少一个字符,那么启用密码输入框,使用户可以输入密码
- 只有当用户名输入框和密码输入框都至少输入一个字符后,OK按钮才处于启用状态,可以被按下
- Cancel按钮总是处于启用状态,任何时候都可以按下该按钮
1.2.1 示例程序类图
1.2.2 Mediator接口
//仲裁者接口
public interface Mediator {
public abstract void createColleagues();//生成仲裁者要管理的组员
public abstract void colleagueChanged();//该方法会被各个组员调用,表示组员向仲裁者进行报告
}
1.2.3 Colleague接口
//表示向仲裁者进行报告的组员的接口
public interface Colleague {
public abstract void setMediator(Mediator mediator);//为组员设置仲裁者
public abstract void setColleagueEnabled(boolean enabled);//组件的状态
}
1.2.4 Colleague接口的实现类
import java.awt.*;
//button组件
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);//设置状态
}
}
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
//文本框组件
public class ColleagueTextField extends TextField implements Colleague, TextListener {
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);//设置背景色
}
@Override
public void textValueChanged(TextEvent e) {
mediator.colleagueChanged();
}
}
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
//Checkbox组件
public class ColleagueCheckbox extends Checkbox implements Colleague, ItemListener {
private Mediator mediator;
public ColleagueCheckbox(String caption,CheckboxGroup group,boolean state) {
super(caption,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();
}
}
1.2.5 LoginFrame类
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//仲裁者实现类
public class LoginFrame extends Frame implements Mediator, ActionListener {
private ColleagueCheckbox checkGuest;
private ColleagueCheckbox checkLogin;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
public LoginFrame(String title) {
super(title);
setBackground(Color.lightGray);//设置背景色
setLayout(new GridLayout(4,2));//设置布局,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,true);
textUser = new ColleagueTextField("",10);
textPass = new ColleagueTextField("",10);
textPass.setEchoChar('*');
buttonOk = new ColleagueButton("OK");
buttonCancel = new ColleagueButton("Cancel");
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);//开启OK按钮
} else {
buttonOk.setColleagueEnabled(false);
}
} else {//用户名未输入
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(false);
}
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
}
}
1.2.6 Main类
public class Main {
public static void main(String[] args) {
new LoginFrame("Mediator Sample");
}
}
输出为:
1.3 Mediator模式中的角色
- Mediator(仲裁者、中介者):该角色负责定义与Colleague角色进行通信和做出决定的接口API,上述的Mediator接口。
- ConcreteMediator(具体的仲裁者、中介者):该角色负责实现Mediator角色的接口API,负责实际做出决定,上述的LoginFrame类。
- Colleague(同事):该角色负责与Midiator角色进行通信的接口API,上述的Colleague接口。
- ConcreteColleague(具体的同事):该角色负责实现Colleague角色的接口API
- Mediator模式的类图
1.4 其他特点
- 因为中介者把控制各个组件的逻辑处理都放在中介者内,因此当发现问题时,只需要调试中介者即可,可以更快地找到bug。集中处理。
- 随着组件变多,通信线路增加,如果没有中介者,程序结构会变的很复杂。
- ConcreteColleague角色可以复用,但ConcreteMediator角色很难复用(因为具体的中介者依赖于特定的逻辑)。
根据图解设计模式书籍进行整理。