无尽加班何时休--状态模式

1.1 加班,又是加班!

        公司的项目很急,所以要求加班。经理把每个人每天的工作都排得满满的,说做完就可以回家,但是没有任何一个人可以在下班前完成的,基本都得加班,这就等于是自愿加班。我走时还有哥们在加班呢。"
        再急也不能这样呀,长时间加班,没有加班费,士气低落,效率大打折扣。

        "可不是咋地!上午刚上班的时候,效率很高,可以写不少代码,到了中午,午饭一吃完,就犯困,可能是最近太累了,但还不敢休息,因为没有人趴着睡觉的,都说项目急,要抓紧。所以我就这么迷迷糊糊的,到了下午三点多才略微精神点,本想着今天任务还算可以,希望能早点完成,争取不要再加班了。哪知快下班时才发现有一个功能是我理解有误,其实比想象的要复杂得多。唉!苦呀,又多花了三个多钟头,九点多才从公司出来。"
        "哈,那你自己也有问题,对工作量的判断有偏差。在公司还可以通过加班来补偿,要是在高考考场上,哪可能加时间,做不完直接就是玩完。"
        "你说这老板对加班是如何想的呢?难道真的认为加班可以解决问题?我感觉这样赶进度,对代码质量没任何好处。"
        "老板的想法当然是和员工不一样了。员工加班,实际上分为几种,第一种,极有可能是员工为了下班能多上会网,聊聊天,打打游戏,或者是为了学习点新东西,所以这其实根本就不能算是加班,只能算下班时坐在办公座位上。第二种,可能这个员工能力相对差,技术或业务能力不过关,或者动作慢,效率低,那当然应该要加班,而且老板也不会打算给这种菜鸟补偿。"

        "我又没说是指你,除非你真的觉得自己能力差、效率低,是菜鸟。"
        "不过也不得不承认,我现在经验不足确实在效率上是会受些影响的,公司里的一些骨灰级程序员,也不觉得水平特别厉害,但是总是能在下班前后就完成当天任务,而且错误很少。"
        "慢慢来吧,编程水平也不是几天就可以升上去的。虽然今天你很累了,但是通过加班这件事,你也可以学到设计模式。"
        "哦,听到设计模式,我就不感觉累了。来,说说看。"
        "你刚才曾讲到,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬。其实是一种状态的变化,不同的时间,会有不同的状态。你现在用代码来实现一下。"


        "其实就是根据时间的不同,做出判断来实现,是吧?这不是大问题。"

1.2 工作状态--函数版

package code.chapter16.state1;public class Test {static int hour = 0;static boolean workFinished = false; //工作是否完成的标记public static void writeProgram()        {if (hour < 12)System.out.println("当前时间:"+hour+"点 上午工作,精神百倍");else if (hour < 13)System.out.println("当前时间:"+hour+"点 饿了,午饭;犯困,午休。");else if (hour < 17)System.out.println("当前时间:"+hour+"点 下午状态还不错,继续努力");else {if (workFinished)System.out.println("当前时间:"+hour+"点 下班回家了");else {if (hour < 21)System.out.println("当前时间:"+hour+"点 加班哦,疲累之极");else System.out.println("当前时间:"+hour+"点 不行了,睡着了。");}}}public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		hour = 9;writeProgram();hour = 10;writeProgram();hour = 12;writeProgram();hour = 13;writeProgram();hour = 14;writeProgram();hour = 17;//workFinished = true;  //任务完成,下班workFinished = false;   //任务未完成,继续加班writeProgram();hour = 19;writeProgram();hour = 22;writeProgram();System.out.println();System.out.println("**********************************************");}}

要有面向对象的思维,至少应该有个工作类

1.3 工作状态--分类版

package code.chapter16.state2;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		//紧急项目Work emergencyProjects = new Work();emergencyProjects.setHour(9);emergencyProjects.writeProgram();emergencyProjects.setHour(10);emergencyProjects.writeProgram();emergencyProjects.setHour(12);emergencyProjects.writeProgram();emergencyProjects.setHour(13);emergencyProjects.writeProgram();emergencyProjects.setHour(14);emergencyProjects.writeProgram();emergencyProjects.setHour(17);emergencyProjects.setWorkFinished(false);//emergencyProjects.setWorkFinished(true);emergencyProjects.writeProgram();emergencyProjects.setHour(19);emergencyProjects.writeProgram();emergencyProjects.setHour(22);emergencyProjects.writeProgram();System.out.println();System.out.println("**********************************************");}}//工作类
class Work{//时间钟点private int hour;   public int getHour(){return this.hour;}public void setHour(int value){this.hour = value;}//是否完成工作任务private boolean workFinished = false;   public boolean getWorkFinished(){return this.workFinished;}public void setWorkFinished(boolean value){this.workFinished = value;}public void writeProgram()        {if (hour < 12)System.out.println("当前时间:"+hour+"点 上午工作,精神百倍");else if (hour < 13)System.out.println("当前时间:"+hour+"点 饿了,午饭;犯困,午休。");else if (hour < 17)System.out.println("当前时间:"+hour+"点 下午状态还不错,继续努力");else {if (workFinished)System.out.println("当前时间:"+hour+"点 下班回家了");else {if (hour < 21)System.out.println("当前时间:"+hour+"点 加班哦,疲累之极");else System.out.println("当前时间:"+hour+"点 不行了,睡着了。");}}}
}

1.4 方法过长时坏味道

        "仔细看看,MartinFowler曾在《重构》中写过一个很重要的代码坏味道,叫作'Long Method',方法如果过长其实极有可能是有坏味道了。"
        "你的意思是'Work(工作)'类的'writeProgram(写程序)'方法过长了?不过这里面太多的判断,好像是不太好。但我也想不出来有什么办法解决它。"
        "你要知道,你这个方法很长,而且有很多的判断分支,这也就意味着它的责任过大了。无论是任何状态,都需要通过它来改变,这实际上是很糟糕的。"
        "哦,对的,面向对象设计其实就是希望做到代码的责任分解。这个类违背了'单一职责原则'。但如何做呢?"
"说得不错,由于'writeProgram(写程序)'的方法里有这么多判断,使得任何需求的改动或增加,都需要去更改这个方法了,比如,你们老板也感觉加班有些过分,对于公司的办公室管理以及员工的安全都不利,于是发了一个通知,不管任务再多,员工必须在20点之前离开公司。这样的需求很合常理,所以要满足需求你就得更改这个方法,但真正要更改的地方只涉及17~22点的状态,但目前的代码却是对整个方法做改动,维护出错的风险很大。"
        "你解释了这么多,我的理解其实就是这样写方法违背了'开放-封闭原则'。"
        那么我们应该如何做?
        "把这些分支想办法变成一个又一个的类,增加时不会影响其他类。然后状态的变化在各自的类中完成。"理论讲讲很容易,但实际如何做,我想不出来。"
        "当然,这需要丰富的经验积累,但实际上你是用不着再去重复发明'轮子'了,因为GoF已经为我们针对这类问题提供了解决方案,那就是'状态模式'。"

1.5 状态模式

        状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。[DP]

        "状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断很简单,那就没必要用'状态模式'了。"
状态模式(State)结构图

package code.chapter16.state0;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		Context c = new Context(new ConcreteStateA());c.request();c.request();c.request();c.request();System.out.println();System.out.println("**********************************************");}}//抽象状态类
abstract class State {public abstract void handle(Context context);}//具体状态类A
class ConcreteStateA extends State 
{public void handle(Context context) {context.setState(new ConcreteStateB());}
}//具体状态类B
class ConcreteStateB extends State 
{public void handle(Context context) {context.setState(new ConcreteStateA());}
}//上下文
class Context {private State state;public Context(State state){this.state = state;}//可读写的状态属性,用于读取当前状态和设置新状态public State getState(){return this.state;}public void setState(State value){this.state = value;System.out.println("当前状态:" + this.state.getClass().getName());}public void request(){this.state.handle(this); }
}

        State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
        ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
        Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。

1.6 状态模式的好处与坏处

        "状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来[DP]。"
        "是不是就是将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换[DP]。"
        "说白了,这样做的目的就是为了消除庞大的条件分支语句,大的分支判断会使得它们难以修改和扩展,就像我们最早说的刻版印刷一样,任何改动和变化都是致命的。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖,好比把整个版面改成了一个又一个的活字,此时就容易维护和扩展了。"
        "什么时候应该考虑使用状态模式呢?"
        "当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。另外,如果业务需求某项业务有多个状态,通常都是一些枚举常量,状态的变化都是依靠大量的多分支判断语句来实现,此时应该考虑将每一种业务状态定义为一个State的子类。于是这些对象就可以不依赖于其他对象而独立变化了,某一天客户需要更改需求,增加或减少业务状态或改变状态流程,对你来说都是不困难的事。"
        "哦,明白了,这种需求还是非常常见的。"
        "现在再回过头来看你的代码,那个'Long Method'你现在会改了吗?"

1.7 工作状态--状态模式版

代码结构图

package code.chapter16.state3;public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("《大话设计模式》代码样例");System.out.println();		//紧急项目Work emergencyProjects = new Work();emergencyProjects.setHour(9);emergencyProjects.writeProgram();emergencyProjects.setHour(10);emergencyProjects.writeProgram();emergencyProjects.setHour(12);emergencyProjects.writeProgram();emergencyProjects.setHour(13);emergencyProjects.writeProgram();emergencyProjects.setHour(14);emergencyProjects.writeProgram();emergencyProjects.setHour(17);emergencyProjects.setWorkFinished(false);//emergencyProjects.setWorkFinished(true);emergencyProjects.writeProgram();emergencyProjects.setHour(19);emergencyProjects.writeProgram();emergencyProjects.setHour(22);emergencyProjects.writeProgram();System.out.println();System.out.println("**********************************************");}
}//抽象状态类
abstract class State {public abstract void writeProgram(Work w);}//上午工作状态
class ForenoonState extends State {public void writeProgram (Work w) {if (w.getHour() < 12)  {System.out.println("当前时间:"+ w.getHour() +"点 上午工作,精神百倍");}else {w.setState(new NoonState());w.writeProgram();}}
}//中午工作状态
class NoonState extends State {public void writeProgram (Work w) {if (w.getHour() < 13)  {System.out.println("当前时间:"+ w.getHour() +"点 饿了,午饭;犯困,午休。");}else {w.setState(new AfternoonState());w.writeProgram();}}
}//下午工作状态
class AfternoonState extends State {public void writeProgram (Work w) {if (w.getHour() < 17) {System.out.println("当前时间:"+ w.getHour() +"点 下午状态还不错,继续努力");}else {w.setState(new EveningState());w.writeProgram();}}  
}//晚间工作状态
class EveningState extends State {public void writeProgram(Work w){if (w.getWorkFinished())  {w.setState(new RestState());w.writeProgram();}else{if (w.getHour() < 21) {System.out.println("当前时间:"+ w.getHour() +"点 加班哦,疲累之极");}else {w.setState(new SleepingState());w.writeProgram();}}}
}//睡眠状态
class SleepingState extends State {public void writeProgram(Work w) {System.out.println("当前时间:"+ w.getHour() +"点 不行了,睡着了。");}
}//下班休息状态
class RestState extends State {public void writeProgram(Work w) {System.out.println("当前时间:"+ w.getHour() +"点 下班回家了");}
}//工作类
class Work {private State current;public Work(){current = new ForenoonState();  }//设置状态public void setState(State value) {this.current = value;}//写代码的状态public void writeProgram() {this.current.writeProgram(this);}//当前的钟点private int hour;public int getHour(){return this.hour;}public void setHour(int value){this.hour = value;}//当前工作是否完成private boolean workFinished = false;public boolean getWorkFinished(){return this.workFinished;}public void setWorkFinished(boolean value){this.workFinished = value;}
}

        抽象状态类,定义一个抽象方法"写程序"。
        上午和中午工作状态类:
        下午和晚间工作状态类:
        睡眠状态和下班休息状态类:
        工作类,此时没有了过长的分支判断语句。
        客户端代码,没有任何改动。但我们的程序却更加灵活易变了。
        "此时的代码,如果要完成我所说的'员工必须在20点之前离开公司',我们只需要怎么样?"
        "增加一个'强制下班状态',并改动一下'晚间工作状态'类的判断就可以了。而这是不影响其他状态的代码的。这样做的确是非常好。"
        "学会了状态模式,我的状态好着呢,让我再体会体会状态模式的美妙。"
        "行了吧你,估计明上午的工作状态,就是睡觉打呼噜了。"
        "唉,这也是公司造成的呀。明天估计还得加班,无尽加班何时休,却道天凉好个秋!"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/599109.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模块十 面向对象

模块十 重点 知道继承的好处会使用继承知道继承之后成员变量以及成员方法的访问特点会方法重写以及知道方法重写的使用场景会使用 this 关键字调用当前对象中的成员会使用super关键字调用父类中的成员会定义抽象类方法以及抽象类会重写抽象方法 第一章 继承 1.1 什么是继承 …

遥感影像处理利器:PyTorch框架下CNN-Transformer,地物分类、目标检测、语义分割和点云分类

目录 专题一 深度卷积网络知识详解 专题二 PyTorch应用与实践&#xff08;遥感图像场景分类&#xff09; 专题三 卷积神经网络实践与目标检测 专题四 卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】 专题五 Transformer与遥感影像目标检测 专题六 Transformer的遥…

Qt:窗口、按钮类、行编辑器、标签类

作业&#xff1a;QQ登录界面 mywidget.h #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QIcon> #include<QMovie> #include <QLabel> #include <QPushButton> #include <QLineEdit> class MyWidget : public QWid…

系统监测工具-tcpdump的使用

一个简单的tcpdump抓包过程。主要抓包观察三次握手&#xff0c;四次挥手的数据包 有两个程序&#xff1a;客户端和服务器两个程序 服务器端的ip地址使用的是回环地址127.0.0.1 端口号使用的是6000 tcpdump -i 指定用哪个网卡等&#xff0c;dstip地址端口指定抓取目的地址…

如何在 iPhone 15/14/13/12/11/XS/XR 上恢复误删除的短信?

无论你的iPhone功能多么强大&#xff0c;数据丢失的情况仍然时有发生&#xff0c;所以当你发现一些重要的消息有一天丢失了。别担心&#xff0c;让自己冷静下来&#xff0c;然后按照本页的方法轻松从 iPhone 中检索已删除的短信。 在这里&#xff0c;您需要奇客数据恢复iPhone…

烤羊肉串引来的思考--命令模式

1.1 吃羊肉串&#xff01; 烧烤摊旁边等着拿肉串的人七嘴八舌地叫开了。场面有些混乱&#xff0c;由于人实在太多&#xff0c;烤羊肉串的老板已经分不清谁是谁&#xff0c;造成分发错误&#xff0c;收钱错误&#xff0c;烤肉质量不过关等。 外面打游击烤羊肉串和这种开门店做烤…

甘特图/横道图制作技巧 - 任务组

在甘特图中通过合理的任务分组可以让项目更加清晰&#xff0c;修改也更方便。 列如下面的甘特图一眼不太容易看清楚整体的进度。或者需要把所有的任务整体的延迟或者提前只能这样一个一个的任务调整&#xff0c;就比较麻烦。 通过给任务分组&#xff0c;看这上面整体的进度就…

Django项目定时任务django-crontab

首先定义一个定时任务函数tasks.py&#xff08;见文章末尾示例&#xff09;&#xff0c;编写函数&#xff0c;然后在setting.py中配置定时任务 1、首先安装django-crontab pip install django-crontab 2、在setting.py中添加应用 (在所有自定义注册app之上) INSTALLED_APPS …

webpack环境配置分类结合vue使用

文件目录结构 按照目录结构创建好文件 控制台执行: npm install /config/webpack.common.jsconst path require(path) const {merge} require(webpack-merge) const {CleanWebpackPlugin} require(clean-webpack-plugin) const { VueLoaderPlugin } require(vue-loader); c…

【Linux系列】“dev-node1“ 运行的操作系统分析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

充电桩项目,开源啦!

好&#xff0c;我是田哥 很多人&#xff0c;最近都在关注我的充电桩项目&#xff0c;之前建了一个微服务架构的项目&#xff0c;也有单体项目的代码开源。 今天&#xff0c;我把最新版微服务架构的充电桩项目源代码开源。 充电桩的输入端与交流电网直接连接&#xff0c;输出端都…

B2985A是德科技B2985A静电计

181/2461/8938产品概述&#xff1a; B2985A 静电计/高阻表具有 0.01 fA&#xff08;0.01 x 10-15 A&#xff09;的分辨率&#xff0c;可帮助您信心十足地测量小电流和最高可达 10 PΩ&#xff08;10 x 1015 Ω&#xff09;的大电阻。 它拥有 4.3 英寸 LCD 彩色液晶屏并配有图形…