一、电梯控制器

电梯在我们周边随处可见,电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑,即使简单点设计,把状态分成开门状态,停止状态和运行状态,操作分成开门、关门、运行、停止,那流程也是很复杂的。首先,开门状态不能开门、运行、停止;停止状态不能关门,停止;运行状态不能开门、关门、运行。要用一个一个if…else…实现,首先代码混乱,不易维护;二是不易扩展。至于各种设计原则什么的……
那该如何实现?在上边的逻辑中,每个操作仅仅是一个操作,状态切换与操作是分离的,这也造成后来操作和状态“相互配合”的“手忙脚乱”。如果把状态抽象成一个类,每个状态为一个子类,每个状态实现什么操作,不实现什么操作,仅仅在这个类中具体实现就可以了。
下面我们实现这个逻辑。
先实现抽象的状态类:

  1. class LiftState:
  2. def open(self):
  3. pass
  4. def close(self):
  5. pass
  6. def run(self):
  7. pass
  8. def stop(self):
  9. pass

而后实现各个具体的状态类:

  1. class OpenState(LiftState):
  2. def open(self):
  3. print "OPEN:The door is opened..."
  4. return self
  5. def close(self):
  6. print "OPEN:The door start to close..."
  7. print "OPEN:The door is closed"
  8. return StopState()
  9. def run(self):
  10. print "OPEN:Run Forbidden."
  11. return self
  12. def stop(self):
  13. print "OPEN:Stop Forbidden."
  14. return self
  15. class RunState(LiftState):
  16. def open(self):
  17. print "RUN:Open Forbidden."
  18. return self
  19. def close(self):
  20. print "RUN:Close Forbidden."
  21. return self
  22. def run(self):
  23. print "RUN:The lift is running..."
  24. return self
  25. def stop(self):
  26. print "RUN:The lift start to stop..."
  27. print "RUN:The lift stopped..."
  28. return StopState()
  29. class StopState(LiftState):
  30. def open(self):
  31. print "STOP:The door is opening..."
  32. print "STOP:The door is opened..."
  33. return OpenState()
  34. def close(self):
  35. print "STOP:Close Forbidden"
  36. return self
  37. def run(self):
  38. print "STOP:The lift start to run..."
  39. return RunState()
  40. def stop(self):
  41. print "STOP:The lift is stopped."
  42. return self

为在业务中调度状态转移,还需要将上下文进行记录,需要一个上下文的类。

  1. class Context:
  2. lift_state=""
  3. def getState(self):
  4. return self.lift_state
  5. def setState(self,lift_state):
  6. self.lift_state=lift_state
  7. def open(self):
  8. self.setState(self.lift_state.open())
  9. def close(self):
  10. self.setState(self.lift_state.close())
  11. def run(self):
  12. self.setState(self.lift_state.run())
  13. def stop(self):
  14. self.setState(self.lift_state.stop())

这样,在进行电梯的调度时,只需要调度Context就可以了。业务逻辑中如下所示:

  1. if __name__=="__main__":
  2. ctx = Context()
  3. ctx.setState(StopState())
  4. ctx.open()
  5. ctx.run()
  6. ctx.close()
  7. ctx.run()
  8. ctx.stop()

打印如下:
STOP:The door is opening…
STOP:The door is opened…
OPEN:Run Forbidden.
OPEN:The door start to close…
OPEN:The dorr is closed
STOP:The lift start to run…
RUN:The lift start to stop…
RUN:The lift stopped…
由逻辑中可知,电梯先在STOP状态,然后开门,开门时运行Run,被禁止,然后,关门、运行、停止。

二、状态模式

状态模式的定义如下:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
行为类设计模式:状态模式 - 图1

三、状态模式的优点和应用场景

优点:

1、状态模式的优点是结构清晰,相比于if…else…简约了不少;
2、封装性好,外部调用不必知道内部实现细节。

应用场景:

1、行为状态改变的场景。这点在各种控制器中非常常见,同时,逻辑结构为状态转移图的场景中都非常适用。

四、状态模式的缺点

1、在状态比较多时,子类也会非常多,不便于管理。