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

news2024/11/18 4:36:48

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.coloradmin.cn/o/1573633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[技术闲聊]我对电路设计的理解(七)-Cadence原理图绘制

一、原理图软件推荐 之前的章节有讲过AD、PADS、Cadence&#xff0c;以及三者的应用标准&#xff0c;今天再讲讲这一点。 如果是学生&#xff0c;可以学习AD软件&#xff0c;因为学校在学习&#xff0c;上手容易&#xff0c;而且即使工作后&#xff0c;如果是电机控制等4层板或…

数据劫持的冲突问题

在近段时间我又再一次使用了数据劫持&#xff0c;发现了一些冲突问题&#xff0c;并在此介绍我所应用的场景。 一、冲突问题 在之前的文章中有介绍过数据劫持&#xff0c;但后来使用的很少&#xff0c;最近在一次使用的过程中&#xff0c;发现了一些问题。 1.value属性的冲突…

第十四届蓝桥杯省赛大学C组(C/C++)填充

原题链接&#xff1a;填充 有一个长度为 n 的 01 串&#xff0c;其中有一些位置标记为 ?&#xff0c;这些位置上可以任意填充 0 或者 1&#xff0c;请问如何填充这些位置使得这个 01 串中出现互不重叠的 0 和 1 子串最多&#xff0c;输出子串个数。 输入格式 输入一行包含一…

【51单片机学习记录】超声波测距

一、超声波测距概述 &#xff08;1&#xff09;超声波时间差测距原理 超声波发射器向某一方向发射超声波&#xff0c;在发射时刻的同时开始计时&#xff0c;超声波在空气中传播&#xff0c;途中碰到障碍物就立即返回来&#xff0c;超声波接收器收到反射波就立即停止计时。超声…

环形链表 - LeetCode 热题 25

大家好&#xff01;我是曾续缘&#x1f970; 今天是《LeetCode 热题 100》系列 发车第 25 天 链表第 4 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可…

道路病害的检测与评估

基于yolov8道路病害的检测与评估 1 安装yolov8并使用 1.下载后: 2.选择为所有用户安装 3.选择一个合适的目录 4.第一个是自动添加环境变量,我们用默认的第二个后边手动添加 5.等待安装 1.1 安装anconda并配置环境变量 安装完成anconda之后,主要用的两个为Anaconda Prompt …

用树莓派获取传感器数据通过Onenet云平台(物模型)传输至微信小程序(上)

前言 为了传输传感器数据&#xff0c;在网上找了很多方法&#xff0c;但都因为各种各样的问题最终没能成功实现。最终找到这个既简单&#xff0c;又方便实现的方法。步骤有点多&#xff0c;希望大家可以跟着教程&#xff0c;一步步耐心的做下去&#xff0c;愿大家都能成功实现数…

ubuntu系统安装systemc-2.3.4流程

背景&#xff1a;systemC编程在linux下的基础环境配置 1&#xff0c;下载安装包&#xff0c;并解压 &#xff08;先下载了最新的3.0.0&#xff0c;安装时候显示sc_cmnhdr.h:115:5: error: #error **** SystemC requires a C compiler version of at least C17 **** &#xff…

idea开发 java web 高校学籍管理系统bootstrap框架web结构java编程计算机网页

一、源码特点 java 高校学籍管理系统是一套完善的完整信息系统&#xff0c;结合java web开发和bootstrap UI框架完成本系统 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 前段主要技术 css jq…

【云计算】云数据中心网络(一):VPC

云数据中心网络&#xff08;一&#xff09;&#xff1a;VPC 1.什么是 VPC2.VPC 的组成2.1 虚拟交换机2.2 虚拟路由器 3.VPC 网络规划3.1 VPC 数量规划3.2 交换机数量规划3.3 地址空间规划3.4 不同规模企业地址空间规划实践 4.VPC 网络高可靠设计4.1 单地域单可用区部署4.2 单地…

【鸿蒙 HarmonyOS】@ohos.promptAction (弹窗)

一、背景 创建并显示文本提示框、对话框和操作菜单。 文档地址&#x1f449;&#xff1a;文档中心 说明 本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 该模块不支持在UIAbility的文件声明处使用&#xff0c;即…

Premiere Pro 2024:赋予创意翅膀,让你的视频飞翔 mac/win版

Premiere Pro 2024&#xff0c;作为Adobe旗下的旗舰视频编辑软件&#xff0c;自推出以来&#xff0c;一直在视频制作领域占据着重要的地位。随着技术的不断进步和创新&#xff0c;Premiere Pro 2024为用户带来了前所未有的编辑体验&#xff0c;重新定义了视频制作的标准。 Pre…

爬虫 新闻网站 以湖南法治报为例(含详细注释) V1.0

目标网站&#xff1a;湖南法治报 爬取目的&#xff1a;为了获取某一地区更全面的在湖南法治报已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 环境&#xff1a;Pycharm2021&#xff0c;Python3.10&#xff0c; 安装的包&#xff1a;requests&#xff0c;csv&#xff…

刷题之Leetcode283题(超级详细)

283.移动零 283. 移动零https://leetcode.cn/problems/move-zeroes/ 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nu…

深度剖析鞋服品牌商品数字化管理的重要性

随着信息技术的迅猛发展与市场竞争的加剧&#xff0c;鞋服品牌商品数字化管理的重要性愈发凸显。数字化管理不仅关乎企业运营效率的提升&#xff0c;更是品牌实现差异化竞争、提升顾客体验、构建智慧零售生态的关键所在。对于鞋服品牌企业而言&#xff0c;提升商品数字化管理的…

P2089 烤鸡、P1706 全排列问题、P1157 组合的输出、P1036 [NOIP2002 普及组] 选数——Python代码实现(带注释)

P2089 烤鸡 题目背景 猪猪 Hanke 得到了一只鸡。 题目描述 猪猪 Hanke 特别喜欢吃烤鸡&#xff08;本是同畜牲&#xff0c;相煎何太急&#xff01;&#xff09;Hanke 吃鸡很特别&#xff0c;为什么特别呢&#xff1f;因为他有 1010 种配料&#xff08;芥末、孜然等&#xf…

面试经典150题——K 个一组翻转链表

1. 题目描述 2. 题目分析与解析 在这里推荐大家看一下这个解题思路&#xff1a; https://www.bilibili.com/video/BV11w411V7Ar/?spm_id_from333.337.search-card.all.click&vd_source7ea7c036902f5cb73c7f4781d1b0eaff 整体的算法思路如下&#xff1a; 初始化&#xff1a…

AWS入门实践-利用S3构建一个静态网站

使用Amazon S3托管静态网站是一个流行的选择&#xff0c;因为它简单、成本效益高&#xff0c;并且易于维护。静态网站由不含服务器端脚本的文件组成&#xff0c;如HTML、CSS和JavaScript文件。下面是使用S3托管静态网站的操作步骤&#xff1a; 如果大家没有AWS免费账号&#x…

【C++】背包问题

目录 背包问题01 背包背包不装满问题背包必须满问题 完全背包 背包问题 背包问题属于动态规划的一类题型 01 背包 背包不装满问题 背包必须满问题 #include <iostream> using namespace std; const int N 1010; #include <vector> int main() {int n , V;int v[…

AJAX —— 学习(三)(完结)

目录 一、jQuery 中的 AJAX &#xff08;一&#xff09;get 方法 1.语法介绍 2.结果实现 &#xff08;二&#xff09;post 方法 1.语法介绍 2.结果实现 &#xff08;三&#xff09;通用型的 AJAX 方法 1.语法介绍 2.结果实现 二、AJAX 工具库 axios &#xff08…