#Mediator
目次
その名の通り、オブジェクト間の関連を仲介者クラスを介することによってなくしてしまおうというのが本パターンです。
テキストボックスに値が入っていないとボタンが有効にならない、というような仕様をよく見かけます。
これはテキストボックスオブジェクトがボタンオブジェクトを知っていなければ(インスタンス変数として保持していなければ)実現できません。
このようなシンプルな仕様では直接関連していても問題はないかもしれませんが、もっと複雑な機能になるといくつものオブジェクトをあるクラスが知っていなければならなくなります。
それを仲介者クラスを使ってなくします。
やはり、どのようなパターンも直交性を高めることに帰結しますね。
##目的
オブジェクト群の相互作用をカプセル化するオブジェクトを定義する。Mediator パターンは、オブジェクト同士がお互いを明示的に参照し合うことがないようにして、結合度を低めることを促進する。それにより、オブジェクトの相互作用を独立に変えることができるようになる。
##構成要素
・Mediator 仲介者抽象クラス
・ConcreteMediator 仲介者具象クラス
・Colleague 色々なオブジェクトと関連したいオブジェクト
##実装
チェックボックス、テキストボックス、ボタンオブジェクトを実装します。
テキストボックスはチェックボックスのどれかにチェックが入っていないと入力ができません。
ボタンはチェックボックスにチェックが入っているかつテキストボックスに入力がないと押下できません。
###Mediator 仲介者抽象クラス
package mediator
interface Mediator {
/**
* ボタン押下可否
*/
fun buttonPress(): Boolean
/**
* テキストボックス入力可否
*/
fun inputTextBox(): Boolean
}
###ConcreteMediator 仲介者具象クラス
package mediator
class ConcreteMediator: Mediator {
var checkBox: CheckBox? = null
var textBox: TextBox? = null
var button: Button? = null
override fun buttonPress(): Boolean {
return checkBox?.sex != null && textBox?.value?.isNotEmpty() ?: false
}
override fun inputTextBox(): Boolean {
return checkBox?.sex != null
}
}
###Colleague 色々なオブジェクトと関連したいオブジェクト
抽象クラス
package mediator
interface Colleague {
enum class Type {
CheckBox,
TextBox,
Button
}
val type: Type
val mediator: Mediator
}
具象クラス
・チェックボックス
package mediator
class CheckBox(override val mediator: Mediator): Colleague {
override val type = Colleague.Type.CheckBox
enum class Sex {
Male,
Female
}
var sex: Sex? = null
fun select(sex: Sex) {
this.sex = sex
}
}
・テキストボックス
package mediator
class TextBox(override val mediator: Mediator): Colleague {
override val type = Colleague.Type.TextBox
var value = ""
fun input(value: String) {
if (mediator.inputTextBox()) {
this.value = value
println("テキストボックス入力成功")
} else {
println("テキストボックス入力失敗")
}
}
}
・ボタン
package mediator
class Button(override val mediator: Mediator): Colleague {
override val type = Colleague.Type.Button
fun press() {
if (mediator.buttonPress()) {
println("ボタン押下成功")
} else {
println("ボタン押下失敗")
}
}
}
###使う人
package mediator
class Client {
init {
val mediator = ConcreteMediator()
val checkBox = CheckBox(mediator)
val textBox = TextBox(mediator)
val button = Button(mediator)
mediator.checkBox = checkBox
mediator.textBox = textBox
mediator.button = button
// テキストボックス入力 チェックボックスが選択されていないため入力失敗
textBox.input("山田太郎")
// チェックボックス選択
checkBox.select(CheckBox.Sex.Female)
// ボタン押下 テキストボックスが入力されていないため失敗
button.press()
// テキストボックス入力 成功!!!
textBox.input("山田花子")
// ボタン押下 成功!!!
button.press()
}
}
###出力結果
[out-put]
テキストボックス入力失敗
ボタン押下失敗
テキストボックス入力成功
ボタン押下成功
以上