# 模拟水的三种不同状态及其相互转化 # 固态、液态、气态 # 不管是什么状态 都是水 # water类、 SolidState、 LiquiState、 GaseousState(固,液,气)、 state类 # 思想:温度变化会改变状态,不同状态下有不同的行为特征
from abc import ABCMeta, abstractmethod class Water: """水""" def __init__(self, state): self.__temperature = 25 # 默认温度(液态) self.__state = state def setState(self, state): self.__state = state def changeState(self, state): if self.__state: print("由",self.__state.getName(), "变为", state.getName()) else: print("初始化为", state.getName()) self.__state = state def getTemperature(self): return self.__temperature def setTemperature(self, temperature): self.__temperature = temperature if self.__temperature <= 0: self.changeState(SolidState("固态")) elif self.__temperature <= 100: self.changeState(LiquiState("液态")) else: self.changeState(GaseousState("气态")) def riseTemperature(self, step): # 温度上升 self.setTemperature(self.__temperature + step) def declineTemperature(self, step): # 温度下降 self.setTemperature(self.__temperature - step) def behavior(self): # self.__state 就是状态实例化对象(谁来调用就是谁 然后调用不同状态下的behavior方法 固液气 ) self.__state.behavior(self) # print(self.__state) class State(metaclass=ABCMeta): """状态类""" def __init__(self, name): self.__name = name def getName(self): return self.__name @abstractmethod def behavior(self, water): """不同状态下的行为""" pass class SolidState(State): def __init__(self, name): super().__init__(name) def behavior(self, water): print("固态"+str(water.getTemperature())) class LiquiState(State): def __init__(self, name): super().__init__(name) def behavior(self, water): print("液态"+str(water.getTemperature())) class GaseousState(State): def __init__(self, name): super().__init__(name) def behavior(self, water): print("气态"+str(water.getTemperature())) def testState(): # print(LiquiState("液态")) water = Water(LiquiState("液态")) # 实例化water ,将一个状态的实例化对象传进去=state water.behavior() # 核心 # 不管是上升、下降温度或者直接设置温度,都是为了确定温度属于哪一个状态,然后改变状态。通过不同状态来调用不同的行为(behavior) water.riseTemperature(100) water.behavior() # water.setTemperature(-4) # water.behavior() # water.setTemperature(18) # water.behavior() # water.setTemperature(110) # water.behavior() testState()
from abc import ABCMeta, abstractmethod class Context(metaclass=ABCMeta): """状态模式的上下文环境类""" def __init__(self): self.__states = [] # 装着各个状态的实例化对象 self.__curState = None # self.__curState就是状态的实例化对象(谁来就是谁) # 状态变化依赖的属性,当这一个变量由多个变量共同决定时可以将其定义成一个类 self.__stateInfo = 0 def addState(self, state): # 如果状态不在self.__states中,加进去 if state not in self.__states: self.__states.append(state) def changState(self, state): # 改变状态 if state is None: return False print(self.__curState) if self.__curState is None: print("初始化", state.getName()) else: print("由",self.__curState.getName(), "变为", state.getName()) self.__curState = state # 在这对self.__curState 进行改变,开始是none,后面谁需要改变状态就是谁 return True def getState(self): return self.__curState def _setStateInfo(self, stateInfo): # 初始 stateInfo = 25 self.__stateInfo = stateInfo # 每一个状态都判断 25 是不是属于自身范围内的。 isMatch(stateInfo) 返回 true/false # ps: stateInfo < 0 25<0 false for state in self.__states: if state.isMatch(stateInfo): # 如果在其中一个的范围,则将原来的状态变成现在确定的状态 self.changState(state) def _getStateInfo(self): return self.__stateInfo # 复杂状态的定义和接口统一 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
from abc import ABCMeta, abstractmethod class Context(metaclass=ABCMeta): """状态模式的上下文环境类""" def __init__(self): self.__states = [] # 装着各个状态的实例化对象 self.__curState = None # self.__curState就是状态的实例化对象(谁来就是谁) # 状态变化依赖的属性,当这一个变量由多个变量共同决定时可以将其定义成一个类 self.__stateInfo = 0 def addState(self, state): # 如果状态不在self.__states中,加进去 if state not in self.__states: self.__states.append(state) def changState(self, state): # 改变状态 if state is None: return False print(self.__curState) if self.__curState is None: print("初始化", state.getName()) else: print("由",self.__curState.getName(), "变为", state.getName()) self.__curState = state # 在这对self.__curState 进行改变,开始是none,后面谁需要改变状态就是谁 return True def getState(self): return self.__curState def _setStateInfo(self, stateInfo): # 初始 stateInfo = 25 self.__stateInfo = stateInfo # 每一个状态都判断 25 是不是属于自身范围内的。 isMatch(stateInfo) 返回 true/false # ps: stateInfo < 0 25<0 false for state in self.__states: if state.isMatch(stateInfo): # 如果在其中一个的范围,则将原来的状态变成现在确定的状态 self.changState(state) def _getStateInfo(self): return self.__stateInfo # 复杂状态的定义和接口统一 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.__states=[] 中 self.addState(SolidState("固态")) self.addState(LiquiState("液态")) self.addState(GaseousState("气态")) # 设置初始温度为 25 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 declineTemperature(self, step): # 温度下降 self.setTemperature(self.getTemperature() - step) def behavior(self): state = self.getState() if isinstance(state, State): state.behavior(self) # 单例装饰器 def singleton(cls, *args, **kwargs): """构造一个单例的装饰器""" instance = {} def __singleton(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return __singleton @singleton class SolidState(State): """固态""" def __init__(self, name): super().__init__(name) def isMatch(self, stateInfo): return stateInfo < 0 def behavior(self, context): print("固态", context._getStateInfo()) class LiquiState(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()) class GaseousState(State): """气态""" def __init__(self, name): super().__init__(name) def isMatch(self, stateInfo): return stateInfo >= 100 def behavior(self, context): print("气态", context._getStateInfo()) def testState(): # print(LiquiState("液态")) water = Water() # 初始化 # water.behavior() # water.riseTemperature(100) # water.behavior() water.setTemperature(-4) # 设置温度,目的改变状态 water.behavior() # 不同状态下的不同行为 # water.setTemperature(18) # water.behavior() # water.setTemperature(110) # water.behavior() testState() """最少需要三步"""
注意
: 实际场景状态复杂时,可以用一个类去定义stateInfo, 每一种状态只有唯一的实例(单例模式限制)