🐘 【Python】デザインパターン学習 - Stateパターン -
作成日: 2021/07/11
0

注意)このTicketはあくまで自分用のメモ。厳密な定義などは参考サイトを参照のこと

Stateパターンについて学ぶ

今回は参考サイト2で紹介されているJavaのコードを自分なりにpythonに書き直して学習する。それとは別に参考サイト1のコードを改良してchromeの拡張機能でストップウォッチを作成する。

Stateパターンとは

状態による振る舞いをクラスとして切り出し切り替えることができる。(参考サイト1より引用)

pythonでの書き方

from abc import ABCMeta, abstractmethod

class StatePatternYumichan():
    
    def changeState(self,state):
        self.state = state
    
    def morningGreet(self):
        return self.state.morningGreet()
    
    def getProtectionForCold(self):
        return self.state.getProtectionForCold()

class State(metaclass=ABCMeta):
    @abstractmethod
    def morningGreet(self):
        pass

    @abstractmethod
    def getProtectionForCold(self):
        pass

class BadMoodState(State):
    def morningGreet(self):
        return "おお"
    
    def getProtectionForCold(self):
        return "ももひき"

class OrdinaryState(State):
    def morningGreet(self):
        return "おっす!"
    
    def getProtectionForCold(self):
        return "走る"

class LoveMoodState(State):
    def morningGreet(self):
        return "おはよう"
    
    def getProtectionForCold(self):
        return "ピンクの毛糸のパンツ"

if __name__=='__main__':
    yumi = StatePatternYumichan()
    
    yumi.changeState(BadMoodState())
    print(yumi.morningGreet())
    print(yumi.getProtectionForCold())

    yumi.changeState(OrdinaryState())
    print(yumi.morningGreet())
    print(yumi.getProtectionForCold())

    yumi.changeState(LoveMoodState())
    print(yumi.morningGreet())
    print(yumi.getProtectionForCold())

実行結果

おお
ももひき
おっす!
走る
おはよう
ピンクの毛糸のパンツ

書いた感想

Stateパターンを使わないとフラグ(変数)を使ってif文で書くところをクラスの切り替えで実装できるところが凄い。

メモ

各状態(クラス)には同じ名前のメソッドを持たせる。
その名前のメソッドを実行するインスタンスのメソッドを呼ぶコードから実行させる。
インスタンスのメソッドを呼ぶコード自体には状態がない。
インスタンスが状態を表す。
渡すインスタンスを切り替えることで状態を切り替える。
都度状態を表すクラスのインスタンスを生成するのではなく、参考サイト1のように状態を表すクラスのインスタンスを予め生成しておいて、それが入った変数を代入させていく形で切り替えるのが綺麗。

Stateパターンどういったときに使う?

フラグを置いてif文で状態を切り替えるコードを書く場合に使える。
状態があって状態毎に処理があるときに使う。
参考サイト3では状態の遷移についてのコードがある。それを見るに状態クラス内で状態の遷移も実装できる。つまり、状態Aになった後状態Bに必ず遷移するなども実装できる。

書いたコード

github:上記のコード
github:参考サイト1のコードを改良したchrome拡張機能

参考サイト

  1. youtube:Stateパターン【コードで理解する】- プログラミング相談所オンライン
  2. 19.State パターン
  3. wiki:State パターン

フリーランスでpythonエンジニアとして働きたく勉強中。 前職は運用SEとセキュリティエンジニア。 開発は学校で学んだ経験と趣味でやっていた程度。一応前職でも業務の自動化のためにExcel VBAやセキュリティテスト用のWebサイトの開発やセキュリティテストツールの改良などで開発はやっていた。