Python设计模式中的状态模式你了解吗
作者:范桂飓 发布时间:2023-07-14 08:20:28
标签: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


猜你喜欢
- 前言大部分初学编程的人来说刚开始都会练习判断两个数或者三个数的大小,来熟悉某种语言的特性和最基本的if,else循环,当我们学习了更高级的语
- 本文实例为大家分享了opencv矿石图片检测矿石数量的具体代码,供大家参考,具体内容如下原始矿石图片此类图片是高躁图,二值化后图像如下采用膨
- 本文实例讲述了Selenium鼠标与键盘事件常用操作方法。分享给大家供大家参考,具体如下:Selenium是一个用于Web应用程序测试的工具
- 两个跳转语法第一个参数是请求路径,第二个参数是http状态码。c.Redirect("/login",400) &nbs
- 这几年比较火的一个漏洞就是jinjia2之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如 {{1+1}} 而返回了 2 得知
- 前言python作为一门脚本语言,其好处是语法简单,很多东西都已经封装好了,直接拿过来用就行,所以实现同样一个功能,用Python写要比用C
- 本文实现的原理很简单,优化方法是用的梯度下降。后面有测试结果。先来看看实现的示例代码:# coding=utf-8from math imp
- 前言本文主要给大家介绍了关于linux/mac安装mysql忘记密码的相关解决办法,分享出来供大家参考借鉴,下面话不多说了,来一起看看详细的
- MySQL变量很多,其中有一些MySQL变量非常值得我们注意,下面就为您介绍一些值得我们重点学习的MySQL变量,供您参考。1 Thread
- 假设mysql安装在c:盘,mysql数据库的用户名是root,密码是123456,数据库名是database_name,在d:盘根目录下面
- 安装环境:centos 5.4mysql版本:mysql 5.1.xx 采用rpm直接安装所需软件: xtrabackup 1.2.22 采
- 一、问题故事起源于一个查询错漏率的报表:有两个查询结果,分别是报告已经添加的项目和报告应该添加的项目,求报告无遗漏率何为无遗漏?即,应该添加
- OpenCV:图片缩放和图像金字塔对图像进行缩放的最简单方法当然是调用resize函数啦!resize函数可以将源图像精确地转化为指定尺寸的
- 如下所示:# coding=utf-8import osimport os.pathimport reimport arrayimport
- 论文:Interactive Image Warping(1993年Andreas Gustafsson)算法思路:假设当前点为(x,y),
- 本文实例为大家分享了python微信好友删除的具体代码,供大家参考,具体内容如下#weixin.py#coding:utf-8# !/usr
- 1. 将数据库生成使用对象资源管理器能快速创建整个数据的脚本,也能使用默认选项创建单个数据库对象的脚本;用户能在查询编辑器窗口中对文件或剪贴
- jemalloc源于Jason Evans 2006年在BSDcan conference发表的论文:《A Scalable Concurr
- pycharm是一款很流行的编写Python程序的编程软件,这篇文章给大家介绍Pycharm使用教程。1、下载pycharmpycharm是
- IE 浏览器中 CSS Expression 特性的最大的问题:会反复执行,每秒钟可能执行了成百上千次,有严重的性能问题。如何对 CSS E