【笔记整理】图解设计模式 | 导航
定义
Mediator模式中的登场角色
Mediator角色负责定义与Colleague角色进行通信和做出决定的接口(API)。
ConcreteMediator角色负责实现Mediator角色的接口(API),负责实际做出决定。
Colleague角色负责定义与Mediator角色进行通信的接口(API)。
ConcreteColleague角色负责实现Colleague角色的接口(API)。
Mediator模式的类图
拓展思路的要点
面向对象编程可以帮助我们分散处理,避免处理过于集中,也就是说可以“分而治之”。
但有时候,把处理分散在各个类中是不明智的。如果只是将应当分散的处理分散在各个类中,但是没有将应当集中的处理集中起来,那么这些分散的类最终只会导致灾难。
A和B,相互通信线路有两条。
A、B和C,相互通信线路有6条。
A、B、C和D,相互通信线路有12条。
......
如果存在很多相互通信的实例,那么程序结构会变得非常复杂。
如果实例很少就不需要Mediator模式了吗?需要考虑的是,即使最初实例很少,很可能随着需求变更实例数量会慢慢变多,迟早会暴露出问题。
ConcreteColleague角色可以复用(原因:内部无逻辑),但ConcreteMediator角色很难复用(原因:逻辑集中)。
依赖于特定应用程序就意味着难以复用。
相关的设计模式
在Mediator模式中,Mediator角色与Colleague角色进行交互。
而在Facade模式中,Facade角色单方面地使用其他角色来对外提供高层接口(API)。因此,可以说Mediator模式是双向的,而Facade模式是单向的。
有时会使用Observer模式来实现Mediator角色与Colleague角色之间的通信。
代码
public interface Mediator {
// 生成Mediator要管理的组员
void createColleagues();
// 被各个Colleague组员调用,当组员状态发生变化时,该方法会被调用
void colleagueChanged();
}
public class LoginFrame extends Frame implements ActionListener, Mediator {
private static final long serialVersionUID = 1L;
private ColleagueCheckbox checkGuest;
private ColleagueCheckbox checkLogin;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
// 构造函数
// 生成并配置各个Colleague后,显示对话框
@SuppressWarnings("deprecation")
public LoginFrame(String title) {
super(title);
setBackground(Color.lightGray);
// 使用布局管理器生成4x2窗格
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
@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);
}
// 接收来自于Colleague的通知然后判断各colleague的启用/禁用状态
@Override
public void colleagueChanged() {
if (checkGuest.getState()) { // Guest mode
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(false);
} else { // Login mode
textUser.setColleagueEnabled(true);
userpassChanged();
}
}
// 当textUser或textPass文本输入框的文字发生变化时
// 判断各Colleague的启用/禁用状态
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);
}
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
}
}
public interface Colleague {
void setMediator(Mediator mediator);
// 告知组员仲裁者所下达的指示
void setColleagueEnabled(boolean enabled);
}
import java.awt.Button;
public class ColleagueButton extends Button implements Colleague {
private static final long serialVersionUID = 1L;
@SuppressWarnings("unused")
private Mediator mediator;
public ColleagueButton(String caption) {
super(caption);
}
@Override
public void setMediator(Mediator mediator) { // 保存Mediator
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) { // Mediator下达启动/禁用的指示
setEnabled(enabled);
}
}
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {
private static final long serialVersionUID = 1L;
private Mediator mediator;
public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) { // 构造函数
super(caption, group, state);
}
@Override
public void setMediator(Mediator mediator) { // 保存Mediator
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) { // Mediator下达启用/禁用指示
setEnabled(enabled);
}
@Override
public void itemStateChanged(ItemEvent e) { // 当状态发生变化时通知Mediator
mediator.colleagueChanged();
}
}
import java.awt.Color;
import java.awt.TextField;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
public class ColleagueTextField extends TextField implements TextListener, Colleague {
private static final long serialVersionUID = 1L;
private Mediator mediator;
public ColleagueTextField(String text, int columns) { // 构造函数
super(text, columns);
}
@Override
public void setMediator(Mediator mediator) { // 保存Mediator
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) { // Mediator下达启用/禁用的指示
setEnabled(enabled);
setBackground(enabled ? Color.white : Color.lightGray);
}
@Override
public void textValueChanged(TextEvent e) { // 当文字发生变化时通知Mediator
mediator.colleagueChanged();
}
}
public class Main {
public static void main(String[] args) {
new LoginFrame("Mediator Sample");
}
}
注:博客中的图片来自网上。