2.设计模式中状态模式(对象的行为模式)(Python实现)

    科技2022-08-07  97

    1.什么是状态模式?

    2.状态模式的设计思想

    3.状态模式的代码框架模型

    4.分别用框架模型和不用框架模型来处理下面的例子

    5.模型说明

    6. 应用场景

    1.什么是状态模式?

        如水一般,状态即事物所处的某一种形态。状态模式是说一个对象在其内部状态发生改变时,其表现的行为和外在的属性不一样,这个对象看上去就像改变了它的类型一样。因此,状态模式又称为对象的行为模式

    2.状态模式的设计思想

        水有三种不同的状态,冰、水、水蒸气。三种不同的状态有着完全不一样的外在特性。三种状态也是相差巨大,但其实内部组成都是一样的,都是水分子。

         状态模式的核心思想就是一个事物(对象)有多种状态,在不同的状态下所表现出来的行为和属性不一样

    3.状态模式的代码框架模型

    # 引入 ABCMeta 和 abstractmethod 来定义抽象类和抽象方法 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 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

    4.分别用框架模型和不用框架模型来处理下面的例子

     

           用水的三种状态,理解状态模式   

          不管水是什么状态,对象始终是水,所以会有一个 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()

    运行结果:

    5.模型说明

    设计要点                                                                                                                                                                                 在实现状态模式的时候,实现的场景状态有时候会非常复杂,决定状态变化的因素也非常多,我们可以把决定状态变化的属性单独抽象成一个类StateInfo,这样判断状态属性是否符合当前的状态isMatch时,就可以传入更多的信息。      每一种状态应当只有唯一的实例。状态模式的优缺点 (1)优点:                ①封装了状态的转换规则,在状态模式中可以将状态的转换代码封装在环境类中,对状态转换代码进行集中管理,而不是分散在一个个业务逻辑中。                ②将所有的与某个状态有关的行为放到一个类中(称为状态类),使开发人员只专注于该状态下的逻辑开发。                ③允许状态转换逻辑与状态对象合为一体,使用时只需要注入一个不同的状态对象即可,使环境对象拥有不同的行为 (2)​​缺点:               ①会增加系统类​​和对象的个数               ② 状态模式的结构与实现都较为复杂,如果使用不当容易导致 程序结构和代码的混乱     

    6. 应用场景

     (1) 一个对象的行为取决于它的状态,并且它在运行时可能经常改变它的状态,从而改变它的行为。

     (2)一个操作中含有庞大的多分支的条件语句,这些分支依赖于该对象的状态,且每一个分支的业务逻辑都非常复杂时,

               我们可以使用状态模式来拆分不同的分支逻辑,使程序有更好的可读性和可维护性。

     

     

     

    Processed: 0.014, SQL: 8