マーチン・ファウラー氏の「リファクタリング」の本を読んでいるのですが、Stateパターンを使ってリファクタリングする例が載っていました。
それをふまえて自分でも考えてみたのですが、なぜ親クラスと子クラスの間にStateクラスを作るのか、その意義がぴんときていません。
例えばPythonの場合、gitHubに載っていたコードでは、継承関係は Radio - State - AMState/FMState
となっています。
Python
1""" http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/""" 2 3 4class State(object): 5 """Base state. This is to share functionality""" 6 7 def scan(self): 8 """Scan the dial to the next station""" 9 self.pos += 1 10 if self.pos == len(self.stations): 11 self.pos = 0 12 print("Scanning... Station is", self.stations[self.pos], self.name) 13 14 15class AmState(State): 16 def __init__(self, radio): 17 self.radio = radio 18 self.stations = ["1250", "1380", "1510"] 19 self.pos = 0 20 self.name = "AM" 21 22 def toggle_amfm(self): 23 print("Switching to FM") 24 self.radio.state = self.radio.fmstate 25 26 27class FmState(State): 28 def __init__(self, radio): 29 self.radio = radio 30 self.stations = ["81.3", "89.1", "103.9"] 31 self.pos = 0 32 self.name = "FM" 33 34 def toggle_amfm(self): 35 print("Switching to AM") 36 self.radio.state = self.radio.amstate 37 38class Radio(object): 39 """A radio. It has a scan button, and an AM/FM toggle switch""" 40 def __init__(self): 41 """We have an AM state and an FM state""" 42 self.amstate = AmState(self) 43 self.fmstate = FmState(self) 44 self.state = self.amstate 45 46 def toggle_amfm(self): 47 self.state.toggle_amfm() 48 49 def scan(self): 50 self.state.scan() 51 52# Test our radio out 53if __name__ == '__main__': 54 radio = Radio() 55 actions = [radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2 56 actions *= 2 57 58 for action in actions: 59 action()
これを以下のように書き換えても、全く同じように動作しました。
クラスの継承関係を、Radio - AMState/FMState
というように、State
を挟まない形に変えたものです。
Python
1class Radio(object): 2 """A radio. It has a scan button, and an AM/FM toggle switch""" 3 def __init__(self): 4 """We have an AM state and an FM state""" 5 self.amstate = AmState(self) 6 self.fmstate = FmState(self) 7 self.state = self.amstate 8 9 def toggle_amfm(self): 10 self.state.toggle_amfm() 11 12 def scan(self): 13 self.state.scan() 14 15 16class AmState(Radio): 17 def __init__(self, radio): 18 self.radio = radio 19 self.stations = ["1250", "1380", "1510"] 20 self.pos = 0 21 self.name = "AM" 22 23 def toggle_amfm(self): 24 print("Switching to FM") 25 self.radio.state = self.radio.fmstate 26 27 def scan(self): 28 """Scan the dial to the next station""" 29 self.pos += 1 30 if self.pos == len(self.stations): 31 self.pos = 0 32 print("Scanning... Station is", self.stations[self.pos], self.name) 33 34 35class FmState(Radio): 36 def __init__(self, radio): 37 self.radio = radio 38 self.stations = ["81.3", "89.1", "103.9"] 39 self.pos = 0 40 self.name = "FM" 41 42 def toggle_amfm(self): 43 print("Switching to AM") 44 self.radio.state = self.radio.amstate 45 46 def scan(self): 47 """Scan the dial to the next station""" 48 self.pos += 1 49 if self.pos == len(self.stations): 50 self.pos = 0 51 print("Scanning... Station is", self.stations[self.pos], self.name) 52 53# Test our radio out 54if __name__ == '__main__': 55 radio = Radio() 56 actions = [radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2 57 actions *= 2 58 59 for action in actions: 60 action()
このため、なぜStateパターンでは後者でなく前者のようにするのかがよくわかりません。
Javaであれば言語特性上、話が違ってくるのかもしれませんが...
どのような意義があるのでしょうか?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/12/12 00:24