「状態によってオブジェクトの挙動を変えるパターン」パターンです。
if文でも同じことはできますが、委譲を使用することで、挙動の変更がやりやすくなっています。
以下の関数
unmbrella
関数)laundry
関数)
に対して、State(晴れ、くもり、雨)に応じて挙動を変えます。state | 行動 | プログラムとしての動き | |
---|---|---|---|
晴れ | : | 傘は持っていかない | "bring no umbrella"を出力 |
くもり | : | 折り畳み傘を持っていく | "bring folding umbrella"を出力 |
雨 | : | 傘を持っていく | "bring normal umbrella"を出力 |
state | 行動 | プログラムとしての動き | |
---|---|---|---|
晴れ | : | 天日干し | "dry outdoor"を出力 |
くもり | : | 部屋干し | "dry indoor"を出力 |
雨 | : | 部屋干し | "dry indoor"を出力 |
def main():
obj = Context()
obj.umbrella()
obj.laundry()
print("---")
obj.change_state("rain")
obj.umbrella()
obj.laundry()
class State():
def umbrella(self):
raise NotImplementedError("umbrella is abstractmethod")
def laundry(self):
raise NotImplementedError("umbrella is abstractmethod")
class Sunnyday(State):
def umbrella(self):
print("bring no umbrella")
def laundry(self):
print("dry outdoor")
class Cloudyday(State):
def umbrella(self):
print("bring folding umbrella")
def laundry(self):
print("dry indoor")
class Rainyday(State):
def umbrella(self):
print("bring normal umbrella")
def laundry(self):
print("dry indoor")
class Context:
def __init__(self):
self.sunny = Sunnyday()
self.rainy = Rainyday()
self.cloudy = Cloudyday()
self.state = self.sunny
def change_state(self, weather):
if weather == "sunny":
self.state = self.sunny
elif weather == "rain":
self.state = self.rainy
elif weather == "cloud":
self.state = self.cloudy
else:
raise ValueError("change_state method must be in {}".format(["sunny", "rain", "cloud"]))
def umbrella(self):
self.state.umbrella()
def laundry(self):
self.state.laundry()
if __name__ == "__main__":
main()
関数とif文でも同じことはできます。
def umbrella(weather):
if weather == "sunny":
print("bring no umbrella")
elif weather == "rain":
print("bring folding umbrella")
elif weather == "cloud":
print("bring normal umbrella")
def laundry(weather):
# こちらもif文を用いて書き換える必要がある
関数が多くない場合、if文を書き換える手間はあまり多くありませんが、
関数が多い場合、全ての関数を見てif文を書き換える手間が増えます。
Stateパターンを使用した実装では、新しいState追加時に
を書き換えるだけで対応可能です。
変更点をより少ない場所に押し込めるということがこのパターンで達成することができます。
特になし