设计模式十一状态模式:边学边做个生成电子书的工具(python+dart)

234 阅读2分钟

状态模式(State Pattern)

image.png

意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

何时使用:代码中包含大量与对象状态有关的条件语句。

如何解决:将各种具体的状态类抽象出来。

python

from abc import ABCMeta, abstractmethod

class Context(metaclass=ABCMeta):

    """ 状态模式的上下文环境 """

    def __init__(self):

        self.__states = []

        self.__cur_state = None

        # 状态发生变化的依赖属性,当这一变量由多个变量共同决定时可以将其定义成一个类

        self.state_info = 0



    def add_state(self, state):

        """ 添加状态 """



        if state not in self.__states:

            self.__states.append(state)



    def change_state(self, state):

        """ 改变状态 """



        if state is None:

            return False

        if self.__cur_state is None:

            print("初始化为:", state.get_name())

        else:

            print("由", self.__cur_state.get_name(), "变为", state.get_name())

        self.__cur_state = state

        self.add_state(state)

        return True



    def get_state(self):

        """ 获取状态 """



        return self.__cur_state



    def _set_state_info(self, state_info):

        self.__state_info = state_info

        for state in self.__states:

            if state.is_match(state_info):

                self.change_state(state)



    def _get_state_info(self):

        return self.__state_info





class State:

    """ 状态基类(负责状态的定义和接口的统一) """



    def __init__(self, name):

        self.__name = name



    def get_name(self):

        return self.__name



    def is_match(self, state_info):

        """ 状态的属性state_info是否在当前状态的范围"""

        return False



    @abstractmethod

    def behavior(self, context):

        pass
        

class Water(Context):

    """ 水(H2O)"""



    def __init__(self):

        super().__init__()

        self.add_state(SolidState("固态"))

        self.add_state(LiquidState("液态"))

        self.add_state(GaseousState("气态"))

        self.set_temperature(25)



    def get_temperature(self):

        """ 获取温度 """



        return self._get_state_info()



    def set_temperature(self, temperature):

        """ 设置温度 """



        self._set_state_info(temperature)



    def rise_temperature(self, step):

        """ 温度上升 """



        self.set_temperature(self.get_temperature() + step)



    def reduce_temperature(self, step):

        """ 温度下降 """



        self.set_temperature(self.get_temperature() - step)



    def behavior(self):

        """ 不同的行为状态 """



        state = self.get_state()

        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 is_match(self, state_info):

        return state_info < 0



    def behavior(self, context):

        print("我是固态,当前温度:" + str(context._get_state_info()) + "℃")





@singleton

class LiquidState(State):

    """ 液态状态 """



    def __init__(self, name):

        super().__init__(name)



    def is_match(self, state_info):

        return state_info >= 0 and state_info < 100



    def behavior(self, context):

        print("我是液态,当前温度:" + str(context._get_state_info()) + "℃")





@singleton

class GaseousState(State):

    """ 气态状态 """



    def __init__(self, name):

        super().__init__(name)



    def is_match(self, state_info):

        return state_info >= 100



    def behavior(self, context):

        print("我是气态,当前温度:" + str(context._get_state_info()) + "℃")





if __name__ == '__main__':

    water = Water()

    water.behavior()

    water.set_temperature(-4)

    water.behavior()

    water.rise_temperature(18)

    water.behavior()

    water.rise_temperature(110)

    water.behavior()

dart 实现


main(List<String> args) {
  Context context = Context();

  StartState startState = StartState();
  startState.doAction(context);
  print(context.state);

  StopState stopState = new StopState();
  stopState.doAction(context);
  print(context.state);
}

//////////////////////////////////////////////////////////////////

///
/// 创建一个接口
///
abstract class State {
  void doAction(Context context);
}

///
/// 创建 Context 类
///
class Context {
  State? state = null;

  Context();
}

///
/// 创建实现接口的实体类
///
class StartState implements State {
  void doAction(Context context) {
    print("Player is in start state");
    context.state = this;
  }

  @override
  String toString() {
    return "Start State";
  }
}

class StopState implements State {
  void doAction(Context context) {
    print("Player is in stop state");
    context.state = this;
  }

  @override
  String toString() {
    return "Stop State";
  }
}