python工作状态_[Python设计模式] 第16章 上班,干活,下班,加班——状态模式
题目
用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬。
基础版本——函数版
hour = 0
work_finished = False
def write_program():
if hour < 12:
print("当前时间: {} 点, 上午工作,精神百倍".format(hour))
elif hour < 13:
print("当前时间: {} 点, 饿了,午饭,犯困,午休".format(hour))
elif hour < 17:
print("当前时间: {} 点, 下午状态还可以,继续努力".format(hour))
elif work_finished == True:
print("当前时间: {} 点, 收工,下班".format(hour))
elif hour < 21:
print("当前时间: {} 点, 加班中,好累".format(hour))
else:
print("当前时间: {} 点, 不行了,睡着了".format(hour))
hour = 9
write_program()
hour = 10
write_program()
hour = 12
write_program()
hour = 13
write_program()
hour = 14
write_program()
hour = 17
work_finished = True
# work_finished = False
write_program()
hour = 19
write_program()
hour = 22
write_program()
当前时间: 9 点, 上午工作,精神百倍
当前时间: 10 点, 上午工作,精神百倍
当前时间: 12 点, 饿了,午饭,犯困,午休
当前时间: 13 点, 下午状态还可以,继续努力
当前时间: 14 点, 下午状态还可以,继续努力
当前时间: 17 点, 收工,下班
当前时间: 19 点, 收工,下班
当前时间: 22 点, 收工,下班
改进版本1.0——初步封装
class Work():
def __init__(self):
self.hour = 0
self.task_finished = False
def write_program(self):
if self.hour < 12:
print("当前时间: {} 点, 上午工作,精神百倍".format(self.hour))
elif self.hour < 13:
print("当前时间: {} 点, 饿了,午饭,犯困,午休".format(self.hour))
elif self.hour < 17:
print("当前时间: {} 点, 下午状态还可以,继续努力".format(self.hour))
elif self.work_finished == True:
print("当前时间: {} 点, 收工,下班".format(self.hour))
elif self.hour < 21:
print("当前时间: {} 点, 加班中,好累".format(self.hour))
else:
print("当前时间: {} 点, 不行了,睡着了".format(self.hour))
work = Work()
work.hour = 9
work.write_program()
work.hour = 10
work.write_program()
work.hour = 12
work.write_program()
work.hour = 13
work.write_program()
work.hour = 14
work.write_program()
work.hour = 17
work.work_finished = True
# work_finished = False
work.write_program()
work.hour = 19
work.write_program()
work.hour = 22
work.write_program()
当前时间: 9 点, 上午工作,精神百倍
当前时间: 10 点, 上午工作,精神百倍
当前时间: 12 点, 饿了,午饭,犯困,午休
当前时间: 13 点, 下午状态还可以,继续努力
当前时间: 14 点, 下午状态还可以,继续努力
当前时间: 17 点, 收工,下班
当前时间: 19 点, 收工,下班
当前时间: 22 点, 收工,下班
点评
这个类中的write_program方法过长,而且有很多判断分支,意味着它的责任过大了。面向对象设计其实就是希望做到代码的责任分解。所以这个类违背了单一职责原则;
此外,write_program方法里有这么多判断,使得任何需求的改动或增加,都需要去更改这个方法。所以这个类也违背了开放-封闭原则;
状态模式
状态模式,当一个对象的内在状态改变是允许改变其行为,这个对象看起来像是改变了其类。[DP]
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
from abc import ABCMeta, abstractmethod
class State():
__metaclass__ = ABCMeta
@abstractmethod
def handle(self, context):
pass
class StateA(State):
def handle(self, context):
context.set_state(StateB())
class StateB(State):
def handle(self, context):
context.set_state(StateA())
class Context():
def __init__(self, state):
self.state = state
def set_state(self, state):
self.state = state
print("当前状态: {}".format(self.state.__class__))
def request(self):
self.state.handle(self) # 精髓
def main():
context = Context(StateA())
context.request()
context.request()
context.request()
context.request()
main()
当前状态:
当前状态:
当前状态:
当前状态:
状态模式的好处与用处
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。[DP]就是将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcretState中,所以通过定义新的子类可以很容易的增加新的状态和转换[DP]。这样做的目的就是为了消除庞大的条件分支语句,大的分支判断会使得它们难以修改和扩展。状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互之间的依赖。
什么时候需要考虑使用状态模式呢?当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,就可以使用状态模式。另外,如果业务需求某项业务有多个状态,通常都是一些枚举常量,状态的变化都是依靠大量的分支判断语句来实现,此时应该考虑将每一种业务状态定义为一个State子类,这样这些对象就可以不依赖于其他对象而独立变化了,如果某天客户需求改了,增加或减少业务状态或改变状态流程,都不是困难了。
改进版本2.0——状态模式
from abc import ABCMeta, abstractmethod
class State():
__metaclass__ = ABCMeta
@abstractmethod
def write_program(self, work):
pass
class ForenoonState(State):
def write_program(self, work):
if work.hour < 12:
print("当前时间: {} 点, 上午工作,精神百倍".format(work.hour))
else:
work.set_state(NoonState())
work.write_program()
class NoonState(State):
def write_program(self, work):
if work.hour < 13:
print("当前时间: {} 点, 饿了,午饭,犯困,午休".format(work.hour))
else:
work.set_state(AfternoonState())
work.write_program()
class AfternoonState(State):
def write_program(self, work):
if work.hour < 17:
print("当前时间: {} 点, 下午状态还可以,继续努力".format(work.hour))
else:
work.set_state(EveningState())
work.write_program()
class EveningState(State):
def write_program(self, work):
if work.task_finished == True:
work.set_state(RestState())
work.write_program()
elif work.hour < 21:
print("当前时间: {} 点, 加班中,好累".format(work.hour))
else:
work.set_state(SleepingState())
work.write_program()
class SleepingState(State):
def write_program(self, work):
print("当前时间: {} 点, 不行了,睡着了".format(work.hour))
class RestState(State):
def write_program(self, work):
print("当前时间: {} 点, 收工,下班".format(work.hour))
class Work():
def __init__(self, state):
self.state = state
self.hour = 0
self.task_finished = False
def set_state(self, state):
self.state = state
def write_program(self):
self.state.write_program(self) # 精髓
work = Work(ForenoonState())
work.hour = 9
work.write_program()
work.hour = 10
work.write_program()
work.hour = 12
work.write_program()
work.hour = 13
work.write_program()
work.hour = 14
work.write_program()
work.hour = 17
work.work_finished = True
# work_finished = False
work.write_program()
work.hour = 19
work.write_program()
work.hour = 22
work.write_program()
当前时间: 9 点, 上午工作,精神百倍
当前时间: 10 点, 上午工作,精神百倍
当前时间: 12 点, 饿了,午饭,犯困,午休
当前时间: 13 点, 下午状态还可以,继续努力
当前时间: 14 点, 下午状态还可以,继续努力
当前时间: 17 点, 加班中,好累
当前时间: 19 点, 加班中,好累
当前时间: 22 点, 不行了,睡着了
点评
假如老板规定“员工必须在20点之前离开公司”,那么只需要增加一个“强制下班状态”,然后改动一下“傍晚工作状态”就可以了。而这是不影响其他状态的代码的。
python工作状态_[Python设计模式] 第16章 上班,干活,下班,加班——状态模式相关推荐
- python工作技巧_能让你工作事半功倍的python小技巧大合集
导读:Python是目前世界上最流行的编程语言之一.因为: 1. 它容易学习 2. 它用途超广 3. 它有非常多的开源支持(大量的模块和库) 本文作者 Peter Gleeson 是一名数据科学家,日 ...
- 2018年python工作好找吗-Python的发展状况-2018年
Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 这个月早些时候我在加拿大PyCon的演讲让我兴奋不已,在会议期间,我与许多聪明人交谈,似乎每个人都在谈论着 ...
- python工作好找吗-Python好找工作吗 不看会后悔
Python好找工作吗 不看会后悔 时间:2018-01-11 来源:Python前景分析 现在Python可谓是越来越火,当然了学习的人员也是越来越多,但是仍有一部分人仍在观望,担心将来Py ...
- python工作好找吗-python工作好找吗
那么学Python怎样才能轻松找工作呢? 给出以下建议: 由于Python进入国内市场还不太久,所以目前国内也只有北上广深.成都.武汉.杭州等大城市有较多的岗位,所以在投递简历时,我们应该以这些大城市 ...
- python keyboard模块_[python] PyMouse、PyKeyboard用python操作鼠标和键盘
1.PyUserInput 简介 PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块,非常方便使用.支持的平台及依赖如下: Linux - Xlib Mac - Quartz, ...
- python 病毒 基因_#Python#提取基因对应的蛋白质名
提取基因对应的蛋白质官方名 最开始,是需要将基因跟其编码的蛋白质对应起来,找遍了各种数据库都没发现有相关的注释文件,Uniprot作为处理蛋白质的大佬,结果里都有,肯定有办法能够满足需求. 搜索TP5 ...
- java 线程状态_【19期】为什么Java线程没有Running状态?
Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...
- java 线程状态_面试官问:为什么Java线程没有Running状态?我懵了
点击上方"占小狼的博客",选择"设为星标" 本文阅读时间大约4分钟. 来源:https://dwz.cn/dLRLBZab Java虚拟机层面所暴露给我们的状态 ...
- 【笔记整理】图解设计模式 | 第16章 Mediator模式(只有一个仲裁者)
[笔记整理]图解设计模式 | 导航 定义 组员向仲裁者报告,仲裁者向组员下达指示. 当发生麻烦事情的时候,通知仲裁者:当发生涉及全体组员的事情时,也通知仲裁者. 当仲裁者下达指示时,组员会立即执行.团 ...
最新文章
- IntelliJ IDEA for Mac 如何将普通 Java 项目变为 Web 项目
- Spring框架学习笔记03:初探Spring——利用注解配置类取代Spring配置文件
- PyQt5系列(四)Mac10.12上安装Cocoapods
- Nginx+PHP+MySQL+Ubuntu14.04 64位环境搭建
- JavaWeb开发模式
- C语言 第六章 多重循环练习
- Java线程池如何体现自己的用途
- 手机号码归属地数据库下载
- Python3学习笔记_F(垃圾回收)
- 【C/C++】Socket编程实例解析
- 锁客+裂变,这套玩法你觉得怎么样
- Python分布式爬虫打造搜索引擎
- Linux配置JavaWeb环境(JDK+Tmocat+Mysql+Nginx+Redis+IDEA部署)
- 金融应用:信用卡号的合法性验证
- html 复选按钮 全选,JS实现复选按钮控件全选和批量操作
- blueprint 实例
- Redis Geohash指令与位置服务应用
- emplace_back() 和 push_back 的区别
- Oracle 小数点特殊处理
- java如何接收十六进制_JAVA十六进制数据接收与传输