Site icon imageTomoMemo.dev

Memo on programming. Provided by Tomo with passion.

Pythonで学ぶデザインパターン[State]

Icon in a callout block
Python 100Days Challenge Day23

Stateパターンについて解説しますよ。

概要

  • Stateパターンとは、オブジェクトが持つ状態によってその振る舞いを変更する方法
    • 状態ごとの動作を簡単に追加・変更ができる

問題

  • 元々初期のソフトウェア設計時は、状態ごとの振る舞いを1つの巨大な条件分岐でやっていた
  • たくさんの問題が出てきた
    • コードが複雑化してメンテしづらい
    • 状態の追加がむずい
    • オブジェクト指向プログラミングに反する
      • 1つのクラスが複数の責任を持ちすぎてしまう問題
        • 単一責任の原則(Single Responsibility Principle)に反する
        • オープン/クローズドの原則(Open/Closed Principle)にも反する

基本構文

例として、部屋の中で電気をつけたり消したりするケースで考えてみる。

スイッチを実装するには下記のロジックが必要

  • 電気がついている状態(ON)
    • スイッチを押すと電気が消える(OFF状態になる)
  • 電気が消えている状態(OFF)
    • スイッチを押すと電気がつく(ON状態になる)
# スイッチを押すメソッドを持つクラス
class State:
    def press_switch(self, switch):
        pass
        
# 電気がついている状態を表すクラス        
class OnState(State):
    def press_switch(self, switch):
        print(f"電気を消す")
        switch.set_state(OffState())

# 電気が消えている状態を表すクラス       
class OffState(State):
    def press_switch(self, switch):
        print(f"電気をつける")
        switch.set_state(OnState())

# スイッチ自体を表すクラス        
class LightSwitch:
    def __init__(self):
        self.state = OffState()
        
    def set_state(self, state):
        self.state = state
        
    def press( self):
        self.state.press_switch(self)
        
switch = LightSwitch()
switch.press()
switch.press()        
switch.press()

> 
電気をつける
電気を消す
電気をつける

Stateパターンをつかうと、オブジェクト状態によって異なる振る舞いが実装しやすい。

「寝る前照明」のような新しい状態を追加したい場合、新しいStateクラスを作成して、必要に応じて状態を切り替えるコードを追加すればOK。

Powered by Tomo with passion.