网络编程
位置:首页>> 网络编程>> Python编程>> Python设计模式中的状态模式你了解吗

Python设计模式中的状态模式你了解吗

作者:范桂飓  发布时间:2023-07-14 08:20:28 

标签:Python,设计模式,状态模式

状态模式

状态模式,当对象的内部状态发生了改变的时候,允许对象执行不同的流程。

Python设计模式中的状态模式你了解吗

优点

  • 封装了状态转换规则。

  • 枚举了可能的状态,在枚举状态之前需要确定状态的种类。

  • 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

  • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

  • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点

  • 状态模式的使用必然会增加系统类和对象的个数。

  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

  • 状态模式对 “开闭原则” 并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

应用场景

  • 行为随状态改变而改变的场景。

  • 条件、分支语句的代替者。

代码示例

Python设计模式中的状态模式你了解吗

这是一个状态图,具有 “有 25 分钱”、“没有 25 分钱”、“售出糖果”、“糖果售罄” 这 4 个状态。同时也对应 4 个动作:“投入 25 分钱”,“退回 25 分钱”,“转动曲柄” 和 “发放糖果”。

class State:
   # 定义state基类
   def insert_quarter(self):
       pass
   def eject_quarter(self):
       pass
   def turn_crank(self):
       pass
   def dispense(self):
       pass

class SoldOutState(State):
   # 继承State 类
   def __init__(self, gumball_machine):
       self.gumball_machine = gumball_machine
   def __str__(self):
       return "sold_out"
   def insert_quarter(self):
       print("You can't insert a quarter, the machine is sold out")
   def eject_quarter(self):
       print("You can't eject, you haven't inserted a quarter yet")
   def turn_crank(self):
       print("You turned, but ther are no gumballs")
   def dispense(self):
       print("No gumball dispensed")

class SoldState(State):
   # 继承State 类
   def __init__(self, gumball_machine):
       self.gumball_machine = gumball_machine
   def __str__(self):
       return "sold"
   def insert_quarter(self):
       print("Please wait, we're already giving you a gumball")
   def eject_quarter(self):
       print("Sorry, you already turned the crank")
   def turn_crank(self):
       print("Turning twice doesn't get you another gumball")
   def dispense(self):
       self.gumball_machine.release_ball()
       if gumball_machine.count > 0:
           self.gumball_machine.state = self.gumball_machine.no_quarter_state
       else:
           print("Oops, out of gumballs!")
           self.gumball_machine.state = self.gumball_machine.soldout_state

class NoQuarterState(State):
   # 继承State 类
   def __init__(self, gumball_machine):
       self.gumball_machine = gumball_machine
   def __str__(self):
       return "no_quarter"
   def insert_quarter(self):
       # 投币 并且改变状态
       print("You inserted a quarter")
       self.gumball_machine.state = self.gumball_machine.has_quarter_state
   def eject_quarter(self):
       print("You haven't insert a quarter")
   def turn_crank(self):
       print("You turned, but there's no quarter")
   def dispense(self):
       print("You need to pay first")

class HasQuarterState(State):
   # 继承State 类
   def __init__(self, gumball_machine):
       self.gumball_machine = gumball_machine
   def __str__(self):
       return "has_quarter"
   def insert_quarter(self):
       print("You can't insert another quarter")
   def eject_quarter(self):
       print("Quarter returned")
       self.gumball_machine.state = self.gumball_machine.no_quarter_state
   def turn_crank(self):
       print("You turned...")
       self.gumball_machine.state = self.gumball_machine.sold_state
   def dispense(self):
       print("No gumball dispensed")

class GumballMachine:
   def __init__(self, count=0):
       self.count = count
       # 找出所有状态,并创建实例变量来持有当前状态,然后定义状态的值
       self.soldout_state = SoldOutState(self)
       self.no_quarter_state = NoQuarterState(self)
       self.has_quarter_state = HasQuarterState(self)
       self.sold_state = SoldState(self)
       if count > 0:
           self.state = self.no_quarter_state
       else:
           self.state = self.soldout_state
   def __str__(self):
       return ">>> Gumball machine current state: %s" % self.state
   def insert_quarter(self):
       # 投入25分钱
       self.state.insert_quarter()
   def eject_quarter(self):
       # 退回25分
       self.state.eject_quarter()
       # print("state", self.state, type(self.state))
   def turn_crank(self):
       # 转动曲柄
       # print("state", self.state, type(self.state))
       self.state.turn_crank()
   def release_ball(self):
       # 发放糖果
       print("A gumball comes rolling out the slot...")
       if self.count > 0:
           self.count -= 1

if __name__ == "__main__":
   # 以下是代码测试
   gumball_machine = GumballMachine(5) # 装入5 个糖果
   print(gumball_machine)
   gumball_machine.insert_quarter() # 投入25分钱
   gumball_machine.turn_crank() # 转动曲柄
   print(gumball_machine)
   gumball_machine.insert_quarter() #投入25分钱
   gumball_machine.eject_quarter()  # 退钱
   gumball_machine.turn_crank()     # 转动曲柄
   print(gumball_machine)
   gumball_machine.insert_quarter() # 投入25分钱
   gumball_machine.turn_crank() # 转动曲柄
   gumball_machine.insert_quarter() # 投入25分钱
   gumball_machine.turn_crank()  # 转动曲柄
   gumball_machine.eject_quarter() # 退钱
   print(gumball_machine)

来源:https://blog.csdn.net/Jmilk/article/details/122933989

0
投稿

猜你喜欢

  • PHP crc32() 函数实例输出 crc32() 的结果:<?php $str = crc32("Hello World
  •     在许多网页中,当鼠标移到一张图片上时,又弹出另一张图片,做这种广告条,要用到Macromedia Dr
  • 如题:我写入关键字到数据库,多的时候用|隔开了,我提取再做相关文章搜索的时候,我怎么提取用|隔开的文字啊,这样我就好用关键字做搜索啊 回复:
  • 以下的文章主要是介绍MySQL5创建存储过程的实例演示,MySQL5创建存储在实际操作中应用的频率还是很高的,以下就是MySQL5创建存储过
  • MySQL由于它本身的小巧和操作的高效, 在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由
  • 本次薯片会讨论了关于分类与类型的问题。怎么找一个item?页面导航一般分类为主,在具体的分类展示下选择类型:典型例子:炫铃(QQ客户端)当只
  • 大家都知道在Dreamwerver中可以很方便地实现记录集的分页显示,但是生成的代码的确很庞大,影响了网页的显示速度,看起来条理也不是很清晰
  • 今天研究了一下JS的用setAttribute方法实现一个页面两份样式表的效果,具体方法如下:第一步:在连接样式表的元素里定义一个id,例如
  • ASP通过XMLDom在服务器端操作XML文件的主要方法和实现对于小数据量,xml文件在检索更新上于ACCESS有很多优势。我曾经测试过不用
  • 本文实例为大家分享了python绘制汉诺塔的具体代码,供大家参考,具体内容如下源码:import turtleclass Stack: &n
  • 我们经常会在登录一个网站的时候被引导页挡住前进的脚步,这一点在上个世纪到本世纪初的网站中尤其明显,特别是在企业网站里,几乎每个企业网站都会有
  • 如何远程注册DLL?试试下面的代码:<% Response.Buffer = True %&g
  • overflow:hidden 用在div上时很好用,但直接用在td上,好像没有任何效果。td中的文本过长时依然自动换了一行像下面这要设定一
  • 好久没有更新博客了,今天看到论坛上有位朋友问起全屏布局,有点像vc的界面。来了兴趣,就写了一个。运用IE6的怪异模式,通过绝对定位来实现的。
  • 方案5 使用xml参数 对sql server xml类型参数不熟悉的童鞋需要先了解下XQuery概念,这里简单提下XQuery 是用来从
  • '====================================='功能:根据ip地址输出地区'参数:ip
  •  Dim iSet conn=Server.CreateObject("ADODB.Connecti
  •     新建图像文件后选Channels面板,新建Alpha1通道:输入文字;  &nbs
  • 一.正常运行:咱们随便写个文件:# test.pyimport argparseap = argparse.ArgumentParser()
  • 前段时间在开发雨哲树网程序的时候,遇到需要转换地址中的参数,需要用到简单可逆运算的加密功能。在网上找了很多都不理想。因为我需要的这个可逆运算
手机版 网络编程 asp之家 www.aspxhome.com