State

デザインパターンとは

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

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

Note

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

ステートパターンとは?

Stateパターンは状態をクラスで表現したパターンです。

stateパターンを使わずにif文やswitch文を使ってプログラムを生成した場合、新しい状態を作成する時は分岐の中身を書き換えなければいけませんが、状態をクラスとして表現することで何をプログラムすべきなのか良いかはっきりします。

サンプルコード

サンプルコードでは天気の状態をStateパターンでクラス化します。

Stateを使わずに条件分岐を使ってプログラムを作る際は下記のようになりますが、これを修正していきます。

Stateパターンを使っていないコード

func feeling(wether: String) {
    switch wether {
    case "晴れ":
        print("良い気分♪")
    case "雨":♪
        print("ちょっと憂鬱")
    default:
        print("・・・")
    }
}
func item(wether: String) {
    switch wether {
    case "晴れ":
        print("帽子をかぶる")
    case "雨":
        print("傘を持っていく")
    default:
        print("・・・")
    }
}

var wether = "雨"

feeling(wether: wether)
item(wether: wether)

プロトコルで状態を使うメソッドを定義

Stateパターンを使っていないコードを見ると天気によって気分(feeling)と持ち物(item)が変わります。

この2つをプロトコルに定義します。

protocol WetherState {
    func feeling()
    func item()
}

State(状態)クラス

晴れと雨と言う状態をクラスかしました。WetherStateプロトコルに準拠しているため状態によって処理が変わる部分をそれぞれのクラス内で実装しています。

この状態は1つしかないものなのでクラスSingletonで定義します。

class Sunny: WetherState {
    static let wether = Sunny()
    
    private init(){}
    
    func feeling() {
        print("良い気分♪")
    }
    
    func item() {
        print("帽子をかぶる")
    }
    
    
}
class Rain: WetherState {
    static let wether = Rain()
    
    private init(){}
    
    func feeling() {
        print("ちょっと憂鬱")
    }
    
    func item() {
        print("傘を持っていく")
    }
}

呼び出し元

var wether: WetherState = Rain.wether
wether.feeling()
wether.item()

コンソール

ちょっと憂鬱
傘を持っていく

コード一覧

import UIKit

protocol WetherState {
    func feeling()
    func item()
}

class Sunny: WetherState {
    static let wether = Sunny()
    
    private init(){}
    
    func feeling() {
        print("良い気分♪")
    }
    
    func item() {
        print("帽子をかぶる")
    }
}

class Rain: WetherState {
    static let wether = Rain()
    
    private init(){}
    
    func feeling() {
        print("ちょっと憂鬱")
    }
    
    func item() {
        print("傘を持っていく")
    }
}

var wether: WetherState = Rain.wether
wether.feeling()
wether.item()

参考文献

State パターン

IT専科 State パターン

Swiftで学ぶデザインパターン8 (Stateパターン)