python-状态模式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
python-状态模式
说明:
在软件开发过程中,各种应⽤程序可能会根据不同的情况做出不同的处理。
最直接的⽅案就是把所有的可能发⽣的情况都考虑到。
然后使⽤条件语句对不同情况的作出判断并进⾏处理。
但是假如状态⽐较复杂,就会出现多个判断语句,判断语句中⼜包含这各种操作,这显然是不受欢迎的。
状态模式的出现就是为了解决这种问题。
状态模式⽤于解决系统中复杂对象的状态转换以及不同状态下⾏为的封装问题,将⼀个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。
状态模式:允许⼀个对象在其内部状态改变时改变它的⾏为,即不同的状态对应了不同的⾏为。
对象看起来似乎修改了它的类。
很多情况下,⼀个对象的⾏为取决于⼀个或者多个动态变化的属性。
这样的属性叫做状态,这样的对象叫做有状态的对象。
其状态是从事先定义好的⼀系列值中取出的。
当⼀个这样的对象与外部事件产⽣互动时,其内部状态就会改变,从⽽使得系统的⾏为也随之改变。
对于客户端⽽⾔,⽆须关⼼对象状态的转换以及对象所处的当前状态,⽆论对于何种状态的对象,客户端都可以⼀致处理
状态模式的结构
状态模式包含以下3个⾓⾊: Context(环境类) State(抽象状态类) ConcreteState(具体状态类)
实例:
电梯在我们周边随处可见,电梯的控制逻辑中⼼是由电梯控制器实现的。
电梯的控制逻辑,即使简单点设计,把状态分成开门状态,停⽌状态和运⾏状态,操作分成开门、关门、运⾏、停⽌,那流程也是很复杂的。
⾸先,开门状态不能开门、运⾏、停⽌;停⽌状态不能关门,停⽌;运⾏状态不能开门、关门、运⾏。
要⽤⼀个⼀个if…else…实现,⾸先代码混乱,不易维护;⼆是不易扩展。
但是可以看出的是,每个操作仅仅是⼀个操作,状态切换与操作是分离的,这也造成后来操作和状态“相互配合”的“⼿忙脚乱”。
如果把状态抽象成⼀个类,每个状态为⼀个⼦类,每个状态实现什么操作,不实现什么操作,仅仅在这个类中具体实现就可以了。
#实现抽象的状态类
class LiftState:
def open(self):
pass
def close(self):
pass
def run(self):
pass
def stop(self):
pass
#实现各个具体的状态类
class OpenState(LiftState):
def open(self):
print("OPEN:The door is opened...")
return self
def close(self):
print("OPEN:The door start to close...")
print("OPEN:The door is closed")
return StopState()
def run(self):
print("OPEN:Run Forbidden.")
return self
def stop(self):
print("OPEN:Stop Forbidden.")
return self
class RunState(LiftState):
def open(self):
print("RUN:Open Forbidden.")
return self
def close(self):
print("RUN:Close Forbidden.")
return self
def run(self):
print("RUN:The lift is running...")
return self
def stop(self):
print("RUN:The lift start to stop...")
print("RUN:The lift stopped...")
return StopState()
class StopState(LiftState):
def open(self):
print("STOP:The door is opening...")
print("STOP:The door is opened...")
return OpenState()
def close(self):
print("STOP:Close Forbidden")
return self
def run(self):
print("STOP:The lift start to run...")
return RunState()
def stop(self):
print("STOP:The lift is stopped.")
return self
#为在业务中调度状态转移,还需要将上下⽂进⾏记录,需要⼀个上下⽂的类
class Context:
lift_state=""
def getState(self):
return self.lift_state
def setState(self,lift_state):
self.lift_state=lift_state
def open(self):
self.setState(self.lift_state.open())
def close(self):
self.setState(self.lift_state.close())
def run(self):
self.setState(self.lift_state.run())
def stop(self):
self.setState(self.lift_state.stop())
#这样,在进⾏电梯的调度时,只需要调度Context就可以了。
业务逻辑中如下
if__name__=="__main__":
ctx = Context()
ctx.setState(StopState())
ctx.open()
ctx.run()
ctx.close()
ctx.run()
ctx.stop()
打印结果:
STOP:The door is opening...
STOP:The door is opened...
OPEN:Run Forbidden.
OPEN:The door start to close...
OPEN:The door is closed
STOP:The lift start to run...
RUN:The lift start to stop...
RUN:The lift stopped...
模式优点
封装了状态的转换规则,可以对状态转换代码进⾏集中管理,⽽不是分散在⼀个个业务⽅法中。
将所有与某个状态有关的⾏为放到⼀个类中,只需要注⼊⼀个不同的状态对象即可使环境对象拥有不同的⾏为。
允许状态转换逻辑与状态对象合成⼀体,⽽不是提供⼀个巨⼤的条件语句块,可以避免使⽤庞⼤的条件语句来将业务⽅法和状态转换代码交织在⼀起。
可以让多个环境对象共享⼀个状态对象,从⽽减少系统中对象的个数。
模式缺点
会增加系统中类和对象的个数,导致系统运⾏开销增⼤。
结构与实现都较为复杂,如果使⽤不当将导致程序结构和代码混乱,增加系统设计的难度。
对开闭原则的⽀持并不太好,增加新的状态类需要修改负责状态转换的源代码,否则⽆法转换到新增状态;⽽且修改某个状态类的⾏为也需要修改对应类的源代码。
模式适⽤环境
对象的⾏为依赖于它的状态(例如某些属性值),状态的改变将导致⾏为的变化。
在代码中包含⼤量与对象状态有关的条件语句,这些条件语句的出现会导致代码的可维护性和灵活性变差,不能⽅便地增加和删除状态,并且导致客户类与类库之间的耦合增强。