源码地址:https://github.com/weilanhanf/PythonDesignPatterns

说明:

在软件开发过程中,各种应用程序可能会根据不同的情况做出不同的处理。最直接的方案就是把所有的可能发生的情况都考虑到。然后使用条件语句对不同情况的作出判断并进行处理。但是假如状态比较复杂,就会出现多个判断语句,判断语句中又包含这各种操作,这显然是不受欢迎的。状态模式的出现就是为了解决这种问题。

状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题,将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。

状态模式:允许一个对象在其内部状态改变时改变它的行为,即不同的状态对应了不同的行为。对象看起来似乎修改了它的类。很多情况下,一个对象的行为取决于一个或者多个动态变化的属性。这样的属性叫做状态,这样的对象叫做有状态的对象。其状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之改变。

对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理

状态模式的结构

状态模式包含以下3个角色: Context(环境类) State(抽象状态类) ConcreteState(具体状态类)

实例:

电梯在我们周边随处可见,电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑,即使简单点设计,把状态分成开门状态,停止状态和运行状态,操作分成开门、关门、运行、停止,那流程也是很复杂的。首先,开门状态不能开门、运行、停止;停止状态不能关门,停止;运行状态不能开门、关门、运行。要用一个一个if…else…实现,首先代码混乱,不易维护;二是不易扩展。

但是可以看出的是,每个操作仅仅是一个操作,状态切换与操作是分离的,这也造成后来操作和状态“相互配合”的“手忙脚乱”。如果把状态抽象成一个类,每个状态为一个子类,每个状态实现什么操作,不实现什么操作,仅仅在这个类中具体实现就可以了。

  1. #实现抽象的状态类
  2. class LiftState:
  3. def open(self):
  4. pass
  5. def close(self):
  6. pass
  7. def run(self):
  8. pass
  9. def stop(self):
  10. pass
  11.  
  12. #实现各个具体的状态类
  13. class OpenState(LiftState):
  14. def open(self):
  15. print("OPEN:The door is opened...")
  16. return self
  17. def close(self):
  18. print("OPEN:The door start to close...")
  19. print("OPEN:The door is closed")
  20. return StopState()
  21. def run(self):
  22. print("OPEN:Run Forbidden.")
  23. return self
  24. def stop(self):
  25. print("OPEN:Stop Forbidden.")
  26. return self
  27. class RunState(LiftState):
  28. def open(self):
  29. print("RUN:Open Forbidden.")
  30. return self
  31. def close(self):
  32. print("RUN:Close Forbidden.")
  33. return self
  34. def run(self):
  35. print("RUN:The lift is running...")
  36. return self
  37. def stop(self):
  38. print("RUN:The lift start to stop...")
  39. print("RUN:The lift stopped...")
  40. return StopState()
  41. class StopState(LiftState):
  42. def open(self):
  43. print("STOP:The door is opening...")
  44. print("STOP:The door is opened...")
  45. return OpenState()
  46. def close(self):
  47. print("STOP:Close Forbidden")
  48. return self
  49. def run(self):
  50. print("STOP:The lift start to run...")
  51. return RunState()
  52. def stop(self):
  53. print("STOP:The lift is stopped.")
  54. return self
  55.  
  56. #为在业务中调度状态转移,还需要将上下文进行记录,需要一个上下文的类
  57. class Context:
  58. lift_state=""
  59. def getState(self):
  60. return self.lift_state
  61. def setState(self,lift_state):
  62. self.lift_state=lift_state
  63. def open(self):
  64. self.setState(self.lift_state.open())
  65. def close(self):
  66. self.setState(self.lift_state.close())
  67. def run(self):
  68. self.setState(self.lift_state.run())
  69. def stop(self):
  70. self.setState(self.lift_state.stop())
  71.  
  72. #这样,在进行电梯的调度时,只需要调度Context就可以了。业务逻辑中如下
  73. if __name__=="__main__":
  74. ctx = Context()
  75. ctx.setState(StopState())
  76. ctx.open()
  77. ctx.run()
  78. ctx.close()
  79. ctx.run()
  80. 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...

模式优点

封装了状态的转换规则,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中 。将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。 允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,可以避免使用庞大的条件语句来将业务方法和状态转换代码交织在一起。 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

模式缺点

会增加系统中类和对象的个数,导致系统运行开销增大。 结构与实现都较为复杂,如果使用不当将导致程序结构和代码混乱,增加系统设计的难度 。对开闭原则的支持并不太好,增加新的状态类需要修改负责状态转换的源代码,否则无法转换到新增状态;而且修改某个状态类的行为也需要修改对应类的源代码。

模式适用环境

对象的行为依赖于它的状态(例如某些属性值),状态的改变将导致行为的变化 。在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合增强

python-状态模式的更多相关文章

  1. python设计模式第二十三天【状态模式】

    1.应用场景 (1)通过改变对象的内部状态从而改变对象的行为,一般表现为状态的顺序执行 2.代码实现 #!/usr/bin/env python #!_*_ coding:UTF-8 _*_ from ...

  2. 大话设计模式Python实现-状态模式

    状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 下面是一个状态模式的demo: #!/usr/bin/env python # -*- ...

  3. python设计模式之状态模式

    python设计模式之状态模式 面向对象编程着力于在对象交互时改变它们的状态.在很多问题中,有限状态机(通常名为状态机)是一个非常方便的状态转换建模(并在必要时以数学方式形式化)工具.首先,什么是状态 ...

  4. [Python设计模式] 第16章 上班,干活,下班,加班——状态模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬. ...

  5. Python笔记:设计模式之状态模式

    状态模式可以看做是在运行时改变对象行为的一种方式.状态模式允许对象在其内部状态变化时改变其行为,此时感觉就像对象本身已经改变了一样. 参与者: State接口:State基类,定义不同状态共同需要执行 ...

  6. python 设计模式之状态模式

    1.为什么会出现状态模式? 在软件开发过程中,各种应用程序可能会根据不同的情况做出不同的处理.最直接的方案就是把所有的可能发生的情况都考虑到.然后使用条件语句(if...elseif...elseif ...

  7. Python设计模式(11)-状态模式

    # coding=utf-8 # *状态模式:一个方法的判断逻辑太长,就不容易修改.方法过长,其本质就是,# * 就是本类在不同条件下的状态转移.状态模式,就是将这些判断分开到各个能# * 表示当前状 ...

  8. Atitit. 有限状态机 fsm 状态模式

    Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...

  9. 建议53:用状态模式美化代码,关于python-state工具包的理解

        在<编写高质量代码:改善python程序的91个建议>的建议53:用状态模式美化代码小节中,介绍了状态模式例如以下:就是当一个对象的内在状态改变时,同意改变其行为,但这个对象看起来 ...

  10. <人人都懂设计模式>-状态模式

    同样是水,固态,气态,液态的变化,是由温度引起. 引此为思考状态模式. from abc import ABCMeta, abstractmethod # 引入ABCMeta和abstractmeth ...

随机推荐

  1. 线程中消费者生产者的实例代码(使用Lock类)

    http://www.cnblogs.com/DreamDrive/p/6192685.html 这个是用synchronized关键字实现的. Lock可以替换synchronized. 上面用来做 ...

  2. kafka消费者基本操作

    1.消费消息 消费者以pull的方式获取消息, 每个消费者属于某一个消费组,在创建时不指定消费者的groupId,则该消费者属于默认消费组test-consumer-group ,在配置文件./con ...

  3. T-SQL触发器,限制一次只能删除一条数据

    /****** Object: Trigger [dbo].[trg_del] Script Date: 01/01/2016 12:58:28 ******/ SET ANSI_NULLS ON G ...

  4. Python模块: 命令行解析optionparser

    Python 有两个内建的模块用于处理命令行参数:一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数:另一个是 optparse,它功能强大,而 ...

  5. SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系

    SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系 SOA面向服务的软件架构(Service Oriented Architecture) 是一种计算机软件的设计模式,主要应 ...

  6. java8 Stream使用案例

    1. 原理 Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator. 原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执 ...

  7. offsetHeight,scrollHeight,clientHeight,scrollTop以及pageX,clientX,offsetX,screenX,offsetLeft,style.left等的区别以及使用详解

    一.写在前面 在阅读本文前,希望大家能针对每个属性亲手测试,网上现有的大量相关博客都有不等的概念错误,毕竟亲手实践才能更好的掌握这些概念. 1.pageX,clientX,screenX与offset ...

  8. springboot 单体架构之shiro集成

    这里使用的是eclipse 开发工具 1.springboot 版本是2.0的,引入了2个shiro 的依赖,如下 <parent> <groupId>org.springfr ...

  9. WEB开发框架性能排行与趋势分析

    WEB开发框架性能基准测试解读与趋势分析 TechEmpower的<Web Framework Benchmarks>性能基准测试,是关注Web开发框架发展的重要途径.但是内容数据众多,每 ...

  10. FFmpeg简易播放器的实现-最简版

    本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10040202.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...