Mediatorパターン

###Mediatorパターンとは
「相談役」を用意するパターン。
仕事を行うメンバーは、全体に波及する出来事がおきた時相談役に知らせる。
また、相談役からの指示には素直に応じる。
相談役は、メンバーからの知らせを元に大局的な判断を行い、
各メンバーに指示をだす。

###Mediator(調停者、仲介者)の役
Colleague役と通信を行って、調整を行うためのインターフェースを定める。

````java
package mediator;

public interface Mediator {
	// このMediatorが管理するメンバーを生成する
	public abstract void createColleagues();
	// 相談役への相談
	public abstract void collegueChanged();
}
````

###ConcreteMediator(具体的な調停者、仲介者)の役
Mediator役のインターフェースを実装し、実際の調整を行う。

````java
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役と通信を行うインターフェースを定める。

````java
package mediator;

public interface Colleague {
	public abstract void setMediator(Mediator mediator);
	// 相談役からやってくる指示に該当
	public abstract void setColleagueEnabled(boolean enabled);
}
````

###ConcretrColleague(具体的同僚)の役
Colleague役のインターフェースを実装する。

````java
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);
	}
}
````

````java
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();
	}

}
````

````java
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)は相談役に知らせているだけで、判断は相談役に任せている。

https://github.com/aki0207/mediator

こちらを参考にさせていただきました。
<a href="https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80">増補改訂版Java言語で学ぶデザインパターン入門</a>