Meditor

デザインパターンとは

デザインパターンとはオブジェクト思考開発における先人たちが作り上げてきた便利な設計図です。

Gang of Four通称Gofが1994年に出版した『オブジェクト指向における再利用のためのデザインパターン』の中で23個の設計図が紹介されています。

Note

デザインパターンのサンプルコードはSwift4でまとめます。

メディエーターパターンとは?

Mediatorパターンはオブジェクト同士のメッセージのやりとりの際に各オブジェクトが自由にメッセージをやりとりするのではなく、共通の調停者を通してメッセージのやり取りを行うパターンです。
このパターンではMediatorとColleagueというクラスが登場します。

サンプルコード

サンプルコードでは再生ボタンと停止ボタンの状態をMediatorクラスが管理するようなコードを作りました。

サンプルは再生と停止の2つだけなので直接お互いのon,offを確認しても良いのですが、ボタンが増えて複雑になった際にMediatorパターンは真の力を発揮します。

Mediator

まずはMediatorです。addColleagueでメンバのcolleaguesを追加します。buttonStateで登録しているcolleaguesの中から特定のボタンの状態を探して返します。

protocol Mediator {
    func addColleague(key: String, colleague: Colleague)
    func buttonState(key: String) -> Bool
}

class ButtonMediator: Mediator {
    var colleagues:[String:Colleague] = [:]
    
    func addColleague(key: String, colleague: Colleague) {
        colleagues[key] = colleague
    }
    func buttonState(key: String) -> Bool {
        let buttonState = colleagues[key]!.state
        return buttonState
    }
}

Colleague

inisializerでそれぞれのボタンがメンバにMediatorを保持して自分を登録しています。

protocol Colleague{
    var mediator: Mediator { get }
    var state: Bool { get }
    func changeState()
}

class StartButton: Colleague {
    let mediator: Mediator
    var state: Bool
    
    init(mediator: Mediator, state: Bool) {
        self.state = state
        self.mediator = mediator
        self.mediator.addColleague(key: "start",colleague: self)
    }
    func changeState() {
        state = !state
    }
}

class StopButton: Colleague {
    var mediator: Mediator
    var state: Bool
    
    init(mediator: Mediator, state: Bool) {
        self.state = state
        self.mediator = mediator
        self.mediator.addColleague(key: "stop",colleague: self)
    }
    func changeState() {
        state = !state
    }
}

呼び出し元

let mediator = ButtonMediator()

let start = StartButton(mediator: mediator, state: true)
let stop  = StopButton(mediator: mediator, state: false)

if stop.mediator.buttonState(key: "start") {
    stop.changeState()
    print("停止ボタンがonになりました")
} else {
    print("再生されていません")
}

コンソール

停止ボタンがonになりました

コード一覧

import UIKit

protocol Mediator {
    func addColleague(key: String, colleague: Colleague)
    func buttonState(key: String) -> Bool
}

class ButtonMediator: Mediator {
    var colleagues:[String:Colleague] = [:]
    
    func addColleague(key: String, colleague: Colleague) {
        colleagues[key] = colleague
    }
    func buttonState(key: String) -> Bool {
        let buttonState = colleagues[key]!.state
        return buttonState
    }
}

protocol Colleague{
    var mediator: Mediator { get }
    var state: Bool { get }
    func changeState()
}

class StartButton: Colleague {
    let mediator: Mediator
    var state: Bool
    
    init(mediator: Mediator, state: Bool) {
        self.state = state
        self.mediator = mediator
        self.mediator.addColleague(key: "start",colleague: self)
    }
    func changeState() {
        state = !state
    }
}

class StopButton: Colleague {
    var mediator: Mediator
    var state: Bool
    
    init(mediator: Mediator, state: Bool) {
        self.state = state
        self.mediator = mediator
        self.mediator.addColleague(key: "stop",colleague: self)
    }
    func changeState() {
        state = !state
    }
}

let mediator = ButtonMediator()

let start = StartButton(mediator: mediator, state: true)
let stop  = StopButton(mediator: mediator, state: false)

if stop.mediator.buttonState(key: "start") {
    stop.changeState()
    print("停止ボタンがonになりました")
} else {
    print("再生されていません")
}

参考文献

Mediator パターン(java)

Swiftで学ぶデザインパターン18 (Mediatorパターン)

Mediatorパターン(ruby)