22-Python与设计模式--状态模式
22-Python与设计模式–状态模式
一、电梯控制器
电梯在我们周边随处可见,电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑,即使简单点设计,
把状态分成开门状态,停止状态和运行状态,操作分成开门、关门、运行、停止,那流程也是很复杂的。
首先,开门状态不能开门、运行、停止;停止状态不能关门,停止;运行状态不能开门、关门、运行。
要用一个一个if…else…实现,首先代码混乱,不易维护;二是不易扩展。至于各种设计原则什么的……
那该如何实现?在上边的逻辑中,每个操作仅仅是一个操作,状态切换与操作是分离的,这也造成后来操作和
状态“相互配合”的“手忙脚乱”。如果把状态抽象成一个类,每个状态为一个子类,每个状态实现什么操作,
不实现什么操作,仅仅在这个类中具体实现就可以了。
下面我们实现这个逻辑。
先实现抽象的状态类:
class LiftState:def open(self):passdef close(self):passdef run(self):passdef stop(self):pass
而后实现各个具体的状态类:
class OpenState(LiftState):def open(self):print "OPEN:The door is opened..."return selfdef 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 selfdef stop(self):print "OPEN:Stop Forbidden."return self
class RunState(LiftState):def open(self):print "RUN:Open Forbidden."return selfdef close(self):print "RUN:Close Forbidden."return selfdef run(self):print "RUN:The lift is running..."return selfdef 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 selfdef 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_statedef setState(self,lift_state):self.lift_state=lift_statedef 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 dorr is closed
STOP:The lift start to run… RUN:The lift start to stop… RUN:The
lift stopped…
由逻辑中可知,电梯先在STOP状态,然后开门,开门时运行Run,被禁止,然后,关门、运行、停止。
二、状态模式
状态模式的定义如下:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
三、状态模式的优点和应用场景
优点:
1、状态模式的优点是结构清晰,相比于if…else…简约了不少;
2、封装性好,外部调用不必知道内部实现细节。应用场景:
1、行为状态改变的场景。这点在各种控制器中非常常见,同时,逻辑结构为状态转移图的场景中都非常适用
。
四、状态模式的缺点
1、在状态比较多时,子类也会非常多,不便于管理。
相关文章:
22-Python与设计模式--状态模式
22-Python与设计模式–状态模式 一、电梯控制器 电梯在我们周边随处可见,电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑,即使简单点设计, 把状态分成开门状态,停止状态和运行状态,操作分成开门、关门、运…...
电脑键盘推荐
一、键盘分类 (1)键位个数 目前有75,84,87,98,104,108的。 (2)薄膜键盘和机械键盘 薄膜键盘就是大多数办公室常见的键盘,主要打一个便宜,耐造…...
大数据-之LibrA数据库系统告警处理(ALM-37001 MPPDBServer实例Redo日志缺失)
告警解释 当DN主实例有未同步到DN备实例的xlog日志被删除时,产生该告警。 告警属性 告警ID 告警级别 可自动清除 37001 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称 RoleName 产生告警的角色名称 HostName 产生告警的主机名…...
C#关键字、特性基础及扩展合集(持续更新)
一、基础 Ⅰ 关键字 1、record record(记录),编译器会在后台创建一个类。支持类似于结构的值定义,但被实现为一个类,方便创建不可变类型,成员在初始化后不能再被改变 (C#9新增) …...
单例模式-支持并发的C语言实现
代码实现: c #include <stdio.h> #include <stdlib.h> #include <pthread.h>// 定义单例对象结构体 typedef struct {// 单例对象的数据成员int value; } Singleton;// 静态变量,用于保存唯一实例的指针 static Singleton* instance …...
java_基础_数据类型
1.数据类型 java 语言是强类型语言,对于每一种数据都给出了明确的数据类型,不同的数据类型也分配了不同的内存空间,所以他们的数据大小也不一样的. 数据类型关键字内存占用取值范围整数byte1-128~127short2-32768~32767int4-2的31次方到2的31次方-1long8-2的63次方到2的63次方…...
C++入门第九篇---Stack和Queue模拟实现,优先级队列
前言: 我们已经掌握了string vector list三种最基本的数据容器模板,而对于数据结构的内容来说,其余的数据结构容器基本都是这三种容器的延申和扩展,在他们的基础上扩展出更多功能和用法,今天我们便来模拟实现一下C库中…...
计算机组成原理(计算机系统概述)
目录 一. 计算机的发展二. 计算机硬件的基本组成2.1 早期冯诺依曼机2.2 现代计算机的结构 三. 各硬件的工作原理3.1 主存储器的基本组成3.2 运算器的基本组成3.3 控制器的基本组成 四. 计算机的工作过程 \quad 一. 计算机的发展 计算机系统 硬件 软件 #mermaid-svg-gp2AsYELE…...
Qt手写ListView
创建视图: QHBoxLayout* pHLay new QHBoxLayout(this);m_pLeftTree new QTreeView(this);m_pLeftTree->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑m_pLeftTree->setFixedWidth(300);创建模型和模型项: m_pLeftTree…...
【开源】基于Vue.js的城市桥梁道路管理系统的设计和实现
项目编号: S 025 ,文末获取源码。 \color{red}{项目编号:S025,文末获取源码。} 项目编号:S025,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥…...
2、git进阶操作
2、git进阶操作 2.1.1 分支的创建 命令参数含义git branch (git checkout -b)<new_branch> <old_branch>表示创建分支-d <-D>删除分支 –d如果分支没有合并,git会提醒,-D强制删除-a -v查看分支-m重新命名分支commit id从指定的commi…...
集线器-交换机-路由器
1.集线器(Hub) 集线器就是将网线集中到一起的机器,也就是多台主机和设备的连接器。集线器的主要功能是对接收到的信号进行同步整形放大,以扩大网络的传输距离,是中继器的一种形式,区别在于集线器能够提供多端口服务,也…...
金融众筹模式系统源码 适合创业孵化机构+天使投资机构+投资基金会等 附带完整的搭建教程
随着互联网技术的发展和金融市场的开放,金融众筹模式逐渐成为一种新型的融资方式。这种模式通过互联网平台聚集大量投资者,共同参与到一个项目中,为项目提供资金支持,最终获得投资回报。今天罗峰给大家分享一款金融众筹模式系统源…...
大数据学习(24)-spark on hive和hive on spark的区别
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
SQLite3 数据库学习(六):Qt 嵌入式 Web 服务器详解
参考引用 SQLite 权威指南(第二版)SQLite3 入门 1. Apache 搭建 cgi 环境 1.1 什么是 Apache Apache 是世界使用排名第一的 Web 服务器软件 它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用 1.2 具体搭建流程…...
各平台chatGPT使用体验(国内外)
首推:openAI 地址:https://chat.openai.com/ 这个真的很好用,而且回复的结果也基本让让人满意,个人首推,而且对比国内的除了回答更令人满意外,它更连贯,不像国内的gpt一句一问,跟进…...
机器学习【02】在 Pycharm 里使用 Jupyter Notebook
只有 Pycharm 的 Professional 版才支持 Jupyter Notebook 一.新建一个项目 参考新建项目 二.相关设置 右键你的项目名,新建一个JupyterNotebook文件 新建后发现 点击最右边的install jupyter可以自动安装 也可以使用命令行在对应的虚拟环境中安装 我们使用直…...
什么是proxy代理?
1. 什么是proxy代理 代理(Proxy)是 JavaScript 中一种非常强大而灵活的功能。代理允许你拦截并覆盖对象的默认行为,提供了一种拦截、定制和扩展对象操作的机制。 简单说,就是在访问对象属性或者赋值时,可以做一些额外…...
opencv-python读取的图像分辨率太大不能完全显示
如果使用OpenCV-Python读取的图像分辨率太大,无法完全显示在屏幕上,可以考虑以下几种方法: 1.缩放图像:使用OpenCV的resize函数,将图像缩小到适合屏幕显示的大小。例如,可以将图像的宽度和高度都缩小到屏幕…...
【ArcGIS Pro微课1000例】0038:基于ArcGIS Pro的人口密度分析与制图
文章目录 一、人口密度二、人口密度分析1. 点密度分析2. 核密度分析三、结果比对一、人口密度 人口密度是指单位土地面积上居住的人口数,通常以每平方千米或每公顷内的常住人口为单位计算。人口密度同资源、经济密切结合,因此,科学准确地分析人口密度的分布情况,对合理制定…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
