重點着力於对象交互时状态之变化,本质上相当於实现一个状态机来解决特定领域的一个软件问题,状态机有两个关键部分:状态和转换,其中状态是指系统当前状况;转换則指因某个事件或条件的触发而从一个状态切换到另一个状态,此通常會在一次转换发生之前或之后执行某些动作。
UML图
- 狀態State抽象類:声明对象行为之接口,而行为要与目前对象的状态相关联。
- 狀態ConcreateStateA/ConcreateStateB具体子類:實作State接口的繼承子类,此是实现对象在特定状态下要采取的实际行为。
- 上下文Context類:接受客户傳達的请求並维护当前状态以來引用相關之ConcreteState實例,使得便可根据请求来调用相应狀態之具体子類下的行为。
示例:
# -*- coding: UTF-8 -*-
from abc import ABCMeta,abstractmethod
class State:
@abstractmethod
def Handle(self):
pass
class ConcreteStateA(State):
def Handle(self):
print ("ConcreteStateA")
class ConcreteStateB(State):
def Handle(self):
print ("ConcreteStateB")
class Context:
state=None
def getState(self):
return self.state
def setState(self,state):
self.state = state
def Request(self):
self.state.Handle() #transpond ask
實際業務場景如下:
if __name__==”__main__”:
context = Context()
stateA = ConcreteStateA()
stateB = ConcreteStateB()
context.setState(stateA) #表示目前處於stateA狀態下
context.Request() #轉移請求給指定狀態以執行
輸出:
ConcreteStateA
示例:按钮控制电视
# -*- coding: UTF-8 -*-
from abc import ABCMeta,abstractmethod
class State: #狀態State抽象類
@abstractmethod
def doThis(self):
pass
class StartState(State): #狀態ConcreteState具体子類1
def doThis(self):
print ("TV Switching ON...")
class StopState(State): #狀態ConcreteState具体子類2
def doThis(self):
print ("TV Switching OFF...")
class TVContext: #上下文Context類
state = None
def getState(self):
return self.state
def setState(self,state):
self.state = state
def request(self):
self.state.doThis()
if __name__==’__main__’:
context = TVContext()
context.getState() #目前狀態
start = StartState()
stop = StopState()
context.setState(stop) #指定狀態為stop
context.request() #傳達請求以執行
輸出:
TV Switching OFF...
示例:计算机开机、关机、休眠
# -*- coding: UTF-8 -*-
from abc import ABCMeta,abstractmethod
class ComputerState(object): #狀態State抽象類
name = "State"
allowed = []
def switch(self,state):
if state.name in self.allowed:
print ("Current:",self,"-->switch to new state",state.name)
self.__class__ = state
else:
print ("Current:",self,"-->switch to ",state.name,"no possible")
self.__class__ = state
def __str__(self):
return self.name
class Off(ComputerState): #狀態ConcreteState具体子類
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(object): #上下文Context類
def __init__(self, model = "HP"):
self.model = model
self.state = Off() #指定預設狀態
def change(self,state): #相當於使用setter方法設定狀態則要在此傳入state以transpond給相应狀態具体子類來執行
self.state.switch(state)
if __name__ == "__main__":
comp = Computer()
# Switch on
comp.change(On)
# Switch off
comp.change(Off)
# Switch on again
comp.change(On)
# Suspend
comp.change(Suspend)
# Try to hibernate - cannot !
comp.change(Hibernate)
# switch on back
comp.change(On)
# Finally off
comp.change(Off)
輸出:
Current: off -->switch to new state on
Current: on -->switch to new state off
Current: off -->switch to new state on
Current: on -->switch to new state suspend
Current: suspend -->switch to hibernate no possible
Current: hibernate -->switch to new state on
Current: on -->switch to new state off
状态模式的优缺点
1.优点
1.1 对象的行为在运行时根据状态而改变。
1.2 实现多種針對不同狀態下之對象行为,且日後易于添加新状态来支持额外的行为,此可改善应用程序的灵活性,全面提高代码的可维护性。
2.缺点
2.1 类爆炸:创建的类太多會增加代码量。
2.2 每引入一个新狀態之對象行为則需要在Context类进行相应的更新处理,这使得上下文容易受到新狀態的影响。