from abc import ABCMeta, abstractmethod
# 状态模式关键在于找到使状态发生改变的某个属性或某个某个属性集,比如水的状态的改变关键在于温度
class Context(metaclass=ABCMeta):
"""状态类的上下文环境类"""
def __init__(self):
self.__states = []
self.__curState = None
# 状态发生变化依赖的属性,当这个一变量有多个共同决定时可以将其单独定义为一个类
self.__stateInfo = 0
def addState(self, state):
if state not in self.__states:
self.__states.append(state)
def changeState(self, state):
if state is None:
return False
if self.__curState is None:
print("初始化为", state.getName())
else:
print("由", self.__curState.getName(), "变为", state.getName())
self.__curState = state
self.addState(state)
return True
def getState(self):
return self.__curState
def _setStateInfo(self, stateInfo):
self.__stateInfo = stateInfo
for state in self.__states:
if state.isMatch(stateInfo):
self.changeState(state)
def _getStateInfo(self):
return self.__stateInfo
def behavior(self):
state = self.getState()
if isinstance(state, State):
state.behavior(self)
class State:
"状态的基类"
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
def isMatch(self, stateInfo):
"状态的属性stateInfo是否在当前的状态范围内"
return False
@abstractmethod
def behavior(self, context):
pass
class Water(Context):
def __init__(self):
super().__init__()
self.addState(SolidState("固态"))
self.addState(LiquidState("液态"))
self.addState(GaseousState("气态"))
self.setTemperature(25)
def getTemperature(self):
return self._getStateInfo()
def setTemperature(self, temperature):
self._setStateInfo(temperature)
def riseTemperature(self, step):
self.setTemperature(self.getTemperature()+step)
def reduceTemperature(self, step):
self.setTemperature(self.getTemperature()-step)
class SolidState(State):
def __init__(self, name):
super().__init__(name)
def isMatch(self, stateInfo):
return stateInfo < 0
def behavior(self, context):
print("我性格高冷,当前体温", context._getStateInfo(), "C,我坚硬如铁,放入一冷血动物,请用我砸人,嘿嘿......")
class LiquidState(State):
def __init__(self, name):
super().__init__(name)
def isMatch(self, stateInfo):
return stateInfo >= 0 and stateInfo < 100
def behavior(self, context):
print("我性格温和,当前体温", context._getStateInfo(), "C,我可滋润万物,饮用我可让你活力倍增......")
class GaseousState(State):
def __init__(self, name):
super().__init__(name)
def isMatch(self, stateInfo):
return stateInfo >= 100
def behavior(self, context):
print("我性格热烈,当前体温", context._getStateInfo(), "C,飞向天空是我毕生的梦想,在这你将看不到我的存在,我将达到无我的境界......")
if __name__ == "__main__":
water = Water()
water.setTemperature(40)
water.behavior()