一、什么是状态模式?
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
允许一个对象在其内部状态发生改变时改变其行为,使这个对象看上去就像改变了它的类型一样。
状态模式,又称对象的行为模式。其核心思想为一个对象有多种状态,在不同的状态下所表现出来的行为和属性不一样。
二、框架
三、代码示例
'''
@author: zyh
@file: state.py
@time: 2023/5/4 17:00
'''
from abc import ABCMeta, abstractmethod
class Context(metaclass=ABCMeta):
'''状态模式的上下文环境类'''
def __init__(self) -> None:
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
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) -> None:
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
# @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(),'°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,飞向天空是我的梦想,在这里你看不到我的存在,我将达到无我的境界。')
def testState():
water = Water()
water.behavior()
water.setTemperature(-10)
water.behavior()
water.setTemperature(60)
water.behavior()
water.riseTemperature(50)
water.behavior()
if __name__ == '__main__':
testState()
四、补充说明
在实现状态模式的时候,实现的场景有时候会很复杂,决定状态变化的因素也很多,我们可以把决定状态变化的属性单独抽象成一个类StateInfo
,这样判断状态属性是否符合当前的状态,isMatch
时可以传入更多信息。每一种状态应当只有唯一的实例。
优点:
- 增强了程序的可扩展性,很容易添加一个State;
- 增强了程序的封装性,每个状态的操作都被封装到了一个状态类中。
缺点:
- 会增加系统类和对象的个数;
- 状态模式的结构与实现都较为复杂,如果使用不当容易导致程序混乱。
应用场景:
- 一个对象的行为取决于其状态,并且它在运行时可能经常改变它的状态,从而改变它的行为。
- 如果代码里面存在一个很长的if else列表,而这些分支都是因为不同状态下执行的操作不一样时,可以考虑使用此模式。