13

Python 设计模式——状态模式

 3 years ago
source link: https://rollingstarky.github.io/2020/12/26/python-design-patterns-state-pattern/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python 设计模式——状态模式

发表于 2020-12-26

| 分类于 Python

| 0

| 阅读次数: 2

字数统计: 3.5k

|

阅读时长 ≈ 0:04

行为模式关注的是对象的响应性,它们通过对象之间的交互以实现更复杂的功能。
状态模式是一种行为设计模式,在该模式中,一个对象可以基于其内部状态封装多个行为。比如根据收音机的基本状态(AM/FM),当调谐到 AM 或 FM 频道时,扫描频道的行为就会相应地发生动态的改变。

from abc import abstractmethod, ABCMeta

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


class ConcreteStateB(State):
def handle(self):
print("ConcreteStateB")


class ConcreteStateA(State):
def handle(self):
print("ConcreteStateA")


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

def getState(self):
return self.state

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

def handle(self):
self.state.handle()


context = Context()
stateA = ConcreteStateA()
stateB = ConcreteStateB()

context.setState(stateA)
context.handle()
# => ConcreteStateA

UML

  • State:定义 Handle() 抽象方法的接口。需要通过 ConcreteState 类实现
  • ConcreteState:实现 Handle() 方法,可以根据状态变化定义执行的实际操作
  • Context:接收客户端请求,维护着对象当前状态的引用,以根据请求调用具体的行为
from abc import abstractmethod, ABCMeta

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


class StartState(State):
def doThis(self):
print("TV Switching ON...")


class StopState(State):
def doThis(self):
print("TV Switching OFF...")


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

def getState(self):
return self.state

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

def doThis(self):
self.state.doThis()


context = TVContext()
context.getState()

start = StartState()
stop = StopState()

context.setState(stop)
context.doThis()
# => TV Switching OFF...
class ComputerState:
name = "state"
allowed = []

def switch(self, state):
if state.name in self.allowed:
print("current:", self, " => switching to", state.name)
self.__class__ = state
else:
print("Current:", self, " => switching to", state.name, "not possible.")

def __str__(self):
return self.name


class Off(ComputerState):
name = "off"
allowed = ['on']


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


class Suspend(ComputerState):
name = "suspend"
allowed = ['on']


class Hibernate(ComputerState):
name = "hibernate"
allowed = ['on']


class Computer:
def __init__(self):
self.state = Off()

def change(self, state):
self.state.switch(state)


if __name__ == '__main__':
comp = Computer()
comp.change(On)
comp.change(Off)

comp.change(On)
comp.change(Suspend)
comp.change(Hibernate)
comp.change(On)
comp.change(Hibernate)
# => current: off => switching to on
# => current: on => switching to off
# => current: off => switching to on
# => current: on => switching to suspend
# => Current: suspend => switching to hibernate not possible.
# => current: suspend => switching to on
# => current: on => switching to Hibernate

状态模式的优点

  • 在状态设计模式中,对象的行为是其状态的函数结果,且行为在运行时依旧状态而改变。这消除了对 if/else 或 switch/case 条件逻辑的依赖
  • 使用状态模式,实现多态行为是很方便的,并且易于添加状态来支持额外的行为
  • 状态模式提高了聚合性,针对状态的行为被聚合到 ConcreteState 类中,放置在代码的同一个地方
  • 状态模式不仅改善了扩展应用程序行为时的灵活性,且提高了代码的可维护性。一个 ConcreteState 类即对应一种行为

状态模式的缺点

  • 类爆炸:由于每个状态都需要在 ConcreteState 中定义,可能导致创建太多功能较为单一的类。既增加了代码量,又使得状态机的结构更加难以审查
  • 随着新行为的引入,Context 类需要进行相应的更新以处理每个行为,使得上下文行为更容易受到每个新行为的影响

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK