Python设计模式之状态模式

状态模式概念

  • 一个对象可以基于其内部状态封装多个行为
  • 也可以看做在运行时改变对象行为的一种方式(Python正好擅长这一点)

实现

例子:收音机具有AM/FM两种调频方式和一个扫描按钮,扫描可以扫描到多个FM/AM频道。当用户打开,设置为FM。点击扫描,可以扫到多个有效FM频道。如果改变为AM,扫描只会扫到AM频道。
也就是根据频道状态,改变扫描行为。

from abc import ABCMeta, abstractmethod


class State(metaclass=ABCMeta):
    @abstractmethod
    def handel(self):
        pass


class ConcreteStateA(State):
    def handel(self):
        print('A')


class ConcreteStateB(State):
    def handel(self):
        print('B')


class Context(State):
    def __init__(self):
        self.state = None

    def get_state(self):
        return self.state

    def set_state(self, state):
        self.state = state

    def handel(self):
        self.state.handel()


context = Context()
sA = ConcreteStateA()
sB = ConcreteStateB()
context.set_state(sA)
context.handel()

计算机状态例子

假设计算机有4种状态,开机,关机,休眠,挂起。只有开机情况下能切换到其他3种状态,其他三种状态只能切换到开机。利用状态模式实现:

class ComputerState(object):
    name = 'state'  # 对象状态名称
    allowed = []  # 定义允许进入的状态的对象的列表

    # 改变计算机的状态的方法
    def switch(self, state):
        if state.name in self.allowed:
            print('现状态:', self, ',转换成', state.name, '成功')
            self.__class__ = state
        else:
            print('现状态:', self, ',转换成', state.name, '失败!!')

    def __str__(self):
        return self.name


# 关闭
class Off(ComputerState):
    name = 'off'
    allowed = ['on']


# 打开
class On(ComputerState):
    name = 'on'
    allowed = ['suspend', 'off', 'hibernate']


# 休眠
class Suspend(ComputerState):
    name = 'suspend'
    allowed = ['on']


# 挂起
class Hibernate(ComputerState):
    name = 'hibernate'
    allowed = ['on']


class Computer(object):
    # 初始状态
    def __init__(self, model='MacBook Pro'):
        self.model = model
        self.state = Off()

    # 改变状态
    def change_to(self, state):
        self.state.switch(state)


if __name__ == '__main__':
    computer = Computer()
    computer.change_to(On)
    computer.change_to(Off)
    computer.change_to(On)
    computer.change_to(Suspend)
    # 这里不能挂起,必须要转换为on后才可以
    computer.change_to(Hibernate)
    computer.change_to(On)
    computer.change_to(Hibernate)
    computer.change_to(On)
    computer.change_to(Off)


'''结果
现状态: off ,转换成 on 成功
现状态: on ,转换成 off 成功
现状态: off ,转换成 on 成功
现状态: on ,转换成 suspend 成功
现状态: suspend ,转换成 hibernate 失败!!
现状态: suspend ,转换成 on 成功
现状态: on ,转换成 hibernate 成功
现状态: hibernate ,转换成 on 成功
现状态: on ,转换成 off 成功
'''

状态设计模式优缺点

优点

  • 消除了对if/else或者switch的依赖
  • 易于添加状态
  • 提高聚合性
  • 只添加一个ConcreteState类就可以添加行为,提高可维护性

缺点

  • 类太多了,每个行为都要写类,结构复杂,代码增加
  • 随着新行为(类)的增加,Context都要进行更改,上下文更容易受到新类的影响。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章