情景引入
请大家想象一下一个乱糟糟的开发小组的工作状态。小组中的10个成员虽然-起协同工作,
但是意见难以统-一,总是互相指挥,导致工作始进度始终滞后。不仅如此,他们还都十分在意编码
细节,经常为此争执不下。这时,我们就需要-一个中立的仲裁者站出来说:“各位,请大家将情况报,
告给我,我来负责仲裁。我会从团队整体出发进行考虑,然后下达指示。但我不会评价大家的工作
细节。”这样,当出现争执时大家就会找仲裁者进行商量,仲裁者会负责统一大家的意见。
最后,整个团队的交流过程就变为了组员向仲裁者报告,仲裁者向组员下达指示。组员之间不
再相互询问和相互指示。
在本章中,我们将要学习Mediator模式。
Mediator的意思是“仲裁者”“中介者”。-方面,当发生麻烦事情的时候,通知仲裁者;当发
生涉及全体组员的事情时,也通知仲裁者。当仲裁者下达指示时,组员会立即执行。团队组员之间
不再互相沟通并私自做出决定,而是发生任何事情都向仲裁者报告。另一方面,仲裁者站在整个团
队的角度上对组员上报的事情做出决定。这就是Mediator模式。
在Mediator模式中,“仲裁者”被称为Mediator,各组员被称为Colleague。Colleague 这个单词
很容易拼错,大家可能也不太明白这个英文单词的意思,但在GoF书(请参见附录E[GoF])中就是
这么记述的,因此本书中沿用该术语。
示例程序
功能描述
一个 GUI应用程序,展示了一个登录对话框,用户在其中输入正确的用户名和密码后可以登录
类的一览表
名字 |
说明 |
Mediator |
定义“仲裁者”的接口(API)的接口 |
Colleague |
定义“组员”的接口(API)的接口 |
ColleagueButton |
表示按钮的类。它实现了 Colleague接口 |
ColleagueTextField |
表示文本输入框的类。它实现了 Colleague接口 |
ColleagueCheckBox |
表示勾选框(此处是单选按钮)的类。它实现了 Colleague接口 |
LoginFrame |
表示登录对话框的类。它实现了 Mediator接口 |
Main |
测试程序行为的类 |
UML

主要代码
1 2 3 4
| public interface Mediator { void createColleagues(); void colleagueChanged(); }
|
Colleague 类
1 2 3 4
| public interface Colleague { void setMediator(Mediator mediator); void setColleagueEnabled(boolean enabled); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ColleagueButton extends Button implements Colleague{ private Mediator mediator;
public ColleagueButton(String label) throws HeadlessException { super(label); }
@Override public void setMediator(Mediator mediator) { this.mediator = mediator; }
@Override public void setColleagueEnabled(boolean enabled) { setEnabled(enabled); } }
|
ColleagueTextField 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class ColleagueTextField extends TextField implements TextListener, Colleague { private Mediator mediator;
public ColleagueTextField(String text, int columns) throws HeadlessException { 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();
} }
|
ColleagueCheckBox 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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); setBackground(enabled ? Color.WHITE : Color.lightGray); }
@Override public void itemStateChanged(ItemEvent e) { mediator.colleagueChanged();
} }
|
LoginFrame 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| 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)); createColleagues(); add(checkGuest); add(checkLogin); add(new Label("Username:")); add(textUser); add(new Label("Password:")); add(textPass); add(buttonOk); add(buttonCancel); pack(); show(); }
@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"); 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); userpassChaged(); } }
private void userpassChaged() { 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); } }
|
Main 类
1 2 3 4 5
| public class Main { public static void main(String[] args) { new LoginFrame("Mediator Sample"); } }
|