1.什么是状态模式?
2.状态模式的设计思想
3.状态模式的代码框架模型
4.分别用框架模型和不用框架模型来处理下面的例子
5.模型说明
6. 应用场景
如水一般,状态即事物所处的某一种形态。状态模式是说一个对象在其内部状态发生改变时,其表现的行为和外在的属性不一样,这个对象看上去就像改变了它的类型一样。因此,状态模式又称为对象的行为模式
水有三种不同的状态,冰、水、水蒸气。三种不同的状态有着完全不一样的外在特性。三种状态也是相差巨大,但其实内部组成都是一样的,都是水分子。
状态模式的核心思想就是一个事物(对象)有多种状态,在不同的状态下所表现出来的行为和属性不一样
用水的三种状态,理解状态模式
不管水是什么状态,对象始终是水,所以会有一个 Water类,而它有三种状态,我们可以定义三个状态类,
SolidState、LiquidState、GaseousState; 就单从这三个单词中每个都有个State的后缀,可以抽出一个更抽象的类
这个类就是状态类(State)。
首先不用框架模型
# 引入 ABCMeta 和 abstractmethod 来定义抽象类和抽象方法 from abc import ABCMeta, abstractmethod class Water: """水""" def __init__(self, state): self.__temperature = 25 # 默认常温为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(LiquidState("液态")) else: self.changeState(GaseousState("气态")) # 提升温度 def riseTemperature(self, step): self.setTemperature(self.__temperature + step) # 降低温度 def reduceTemperature(self, step): self.setTemperature(self.__temperature - step) # 表现出的形态 def behavior(self): self.__state.behavior(self) class State(metaclass=ABCMeta): """状态的基类""" def __init__(self, name): self.__name = name def getName(self): return self.__name def isMatch(self, stateInfo): """状态的属性 stateInfo 是否在当前的状态范围""" return False @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 LiquidState(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(): water = Water(LiquidState("液态")) water.behavior() water.setTemperature(-4) water.behavior() water.riseTemperature(18) water.behavior() water.riseTemperature(110) water.behavior() testState()首先设置状态为液态,然后调用behavior()方法,看表现的状态,再进行设置温度,以及提升温度,看它不同的温度所表现的状态
运行结果:
State是抽象状态类(基类),负责状态的定义和接口的统一。
使用框架模式,
# 引入 ABCMeta 和 abstractmethod 来定义抽象类和抽象方法 from abc import ABCMeta, abstractmethod class Context(metaclass=ABCMeta): """状态模式的上下文环境类""" def __init__(self): self.__states = [] self.__curState = None self.__stateInfo = 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 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) 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 class State(metaclass=ABCMeta): """状态的基类""" def __init__(self, name): self.__name = name def getName(self): return self.__name def isMatch(self, stateInfo): """状态的属性 stateInfo 是否在当前的状态范围""" return False @abstractmethod def behavior(self, water): """不同状态下的行为""" pass @singleton class SolidState(State): """固态""" def __init__(self, name): super().__init__(name) def isMatch(self, stateInfo): return stateInfo < 0 def behavior(self, context): print("当前的温度" + str(context.getStateInfo()) + "℃,为固态冰") class LiquidState(State): """液态""" def __init__(self, name): super().__init__(name) def isMatch(self, stateInfo): return 0 <= stateInfo < 100 def behavior(self, context): print("当前的温度" + str(context.getStateInfo()) + "℃,为液态水") class GaseousState(State): """气态""" def __init__(self, name): super().__init__(name) # 当温度大于100,即为气态,范围true def isMatch(self, stateInfo): return stateInfo >= 100 def behavior(self, context): print("当前的温度" + str(context.getStateInfo()) + "℃,为气态水蒸气") def testState(): water = Water() water.behavior() water.setTemperature(-4) # 设置温度 water.behavior() water.riseTemperature(18) # 提升温度18℃ water.behavior() water.riseTemperature(110) # 提升温度110℃ water.behavior() testState()运行结果:
(1) 一个对象的行为取决于它的状态,并且它在运行时可能经常改变它的状态,从而改变它的行为。
(2)一个操作中含有庞大的多分支的条件语句,这些分支依赖于该对象的状态,且每一个分支的业务逻辑都非常复杂时,
我们可以使用状态模式来拆分不同的分支逻辑,使程序有更好的可读性和可维护性。