読者です 読者をやめる 読者になる 読者になる

Template method パターン

Template method パターン

テンンプレートメソッドパターンは、「似たような流れの処理」をスーパークラスで共通化し、「固有の処理」をサブクラスにまかせることで、「処理のテンプレート」を作成するパターンです。

引用: 「サルでもわかる 逆引きデザインパターン」

案件

とあるアイドル2人がいました。

彼女たちはLIVEでは同じように歌って、踊ります。しかし、人気には差があります。

1人はシングル曲の選抜メンバーに選ばれるほどの人気者(kojiharu)で、握手の列が大混雑。

もう1人は研究生で人気はまだまだ(asapon)。握手のレーンはまばらです。

ある日、2人はLIVEを行う事になりました。

LIVEは歌って、踊って、握手をします。

しかし、2人の人気に差があるので、歌って、踊りつつ、握手の対応だけ変えたいということになりました。

実装

// 2人のスーパークラス
class Idol {
    
    func live() {
        sing()
        dance()
        shakeHand()
    }
    
    func sing() {
        print("歌う");
    }
    
    
    func dance() {
        print("踊る");
    }
    
    func shakeHand() {
        fatalError("オーバーライドしてね")
    }
}

// 握手の対応だけ変えます

//人気な選抜メン
class Senbatsu: Idol {
    override func shakeHand() {
        print("サクッと対応する")
    }
}

// 研究生
class Kenkyusei: Idol {
    override func shakeHand() {
        print("ゆっくりファンの人との会話を楽しむ")
    }
}

// kojiharu
let kojiharu = Senbatsu()
kojiharu.live() //歌う 踊る サクッと対応する

//asapon
let asapon = Kenkyusei()
asapon.live() //歌う 踊る ゆっくりファンの人との会話を楽しむ

結果

処理の構造を変えずに、サブクラスで変えたい処理の内容を再定義することができました。

これは継承を使っていますが、委譲を使って同じことを実現するStrategyパターンもあるようなので、後日実装したいです。

継承を使うとスーパークラスの変更があった場合、サブクラスに影響が出るので、委譲を使ったほうがクラスと実装を疎結合にできそうな機運は高まってますね。