Mediatorパターンとは
「相談役」を用意するパターン。
仕事を行うメンバーは、全体に波及する出来事がおきた時相談役に知らせる。
また、相談役からの指示には素直に応じる。
相談役は、メンバーからの知らせを元に大局的な判断を行い、
各メンバーに指示をだす。
Mediator(調停者、仲介者)の役
Colleague役と通信を行って、調整を行うためのインターフェースを定める。
package mediator;
public interface Mediator {
// このMediatorが管理するメンバーを生成する
public abstract void createColleagues();
// 相談役への相談
public abstract void collegueChanged();
}
ConcreteMediator(具体的な調停者、仲介者)の役
Mediator役のインターフェースを実装し、実際の調整を行う。
package mediator;
import java.awt.CheckboxGroup;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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) {
super(title);
setBackground(Color.lightGray);
// レイアウトマネージャーを使って4×2のグリッドを作る
setLayout(new GridLayout(4, 2));
// Colleagueたちの生成
createColleagues();
// 配置
add(checkGuest);
add(checkLogin);
add(new Label("User name:"));
add(textUser);
add(new Label("Password:"));
add(textPass);
add(buttonOk);
add(buttonCancel);
// 有効/無効の初期設定
collegueChanged();
// 表示
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");
// 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からの通知で有効/無効を判定する
@Override
public void collegueChanged() {
if (checkGuest.getState()) {
// Guestモード
textPass.setColleagueEnabled(true);
if (textPass.getText().length() > 0) {
buttonOk.setEnabled(true);
} else {
buttonOk.setEnabled(false);
}
} else {
// Loginモード
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(false);
}
}
// textUserまたはtextPassの変更があった
// 各Colleagueの有効/無効を判定する
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
System.exit(0);
}
}
Colleague(同僚)の役
Mediator役と通信を行うインターフェースを定める。
package mediator;
public interface Colleague {
public abstract void setMediator(Mediator mediator);
// 相談役からやってくる指示に該当
public abstract void setColleagueEnabled(boolean enabled);
}
ConcretrColleague(具体的同僚)の役
Colleague役のインターフェースを実装する。
package mediator;
import java.awt.Button;
/**
* LoginFrameクラス(Mediatorインターフェース)と協調動作を行う
*
*/
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;
}
// Mediatorから有効/無効が指示される
@Override
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
}
}
package mediator;
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 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);
}
// 文字列が変化した場合Mediatorに通知
public void textValueChanged(TextEvent e) {
mediator.collegueChanged();
}
}
package mediator;
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 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.collegueChanged();
}
}
上記のプログラムでは、ボタンの活性、非活性の判断を相談役であるLoginFrameクラスが行っている。
各メンバー(ColleagueButton,TextField,CheckBox)は相談役に知らせているだけで、判断は相談役に任せている。
こちらを参考にさせていただきました。
増補改訂版Java言語で学ぶデザインパターン入門