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

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点之前离开公司',我们只需要怎么样?"
        "增加一个'强制下班状态',并改动一下'晚间工作状态'类的判断就可以了。而这是不影响其他状态的代码的。这样做的确是非常好。"
        "学会了状态模式,我的状态好着呢,让我再体会体会状态模式的美妙。"
        "行了吧你,估计明上午的工作状态,就是睡觉打呼噜了。"
        "唉,这也是公司造成的呀。明天估计还得加班,无尽加班何时休,却道天凉好个秋!"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

查看Linux系统相关信息

注&#xff1a; 本文只是博主学习记录分享&#xff0c;仅供参考。如有错误肯定是博主理解有问题&#xff0c;谢谢&#xff01; 一、查看当前操作系统的内核信息 命令&#xff1a;uname -a 二、查看当前操作系统版本信息 命令&#xff1a;cat /proc/version 这条命令可以查看到…

Your file appears not to be a valid OLE2 document

前言 org.apache.poi.poifs.filesystem.NotOLE2FileException:Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document解决 Excel兼容模式打开老版本文件造成文件损坏&#xff0c;大多说的是点…

OPC UA遇见chatGPT

最近opc 基金会将召开一个会议&#xff0c;主题是”OPC UA meets IT“。由此可见&#xff0c;工业自动化行业也开始研究和评估chatGPT带来的影响了。 本文谈谈本人对OPC UA 与chatGPT结合的初步实验和思考。 构建OPC UA 信息模型 chatGPT 的确非常强大了&#xff0c;使用自然…

Redis 主从复制、哨兵模式、Cluster集群

目录 一、Redis 主从复制 1、主从复制介绍 2、主从复制的作用 3、主从复制流程&#xff1a; 4、搭建redis主从复制 4.1所有服务器搭建redis数据库 4.2修改Redis配置文件&#xff08;Master节点操作&#xff09; ​4.3修改Redis配置文件&#xff08;slave节点操作&#x…

如何搭建企业级MQ消息集成平台

企业级MQ消息集成平台的重要性在于实现不同系统之间的高效、可靠、实时的消息传递和数据交换。它可以帮助企业实现系统解耦&#xff0c;提高系统的可扩展性和灵活性&#xff0c;降低系统间的依赖性。通过消息队列中间件&#xff0c;企业可以实现异步通信、削峰填谷、流量控制等…

Mysql底层原理七:InnoDB 行记录

1.行格式 1.1 Compact行格式 1.1.1 示意图 1.1.2 准备一下 1&#xff09;建表 mysql> CREATE TABLE record_format_demo (-> c1 VARCHAR(10),-> c2 VARCHAR(10) NOT NULL,-> c3 CHAR(10),-> c4 VARCHAR(10)-> ) CHARSETascii ROW_FORMATCOM…

基于支持 GPT 的服务的初创公司

Kafkai&#xff1a;多语言长篇内容生成&#xff0c;AI写作的新趋势 介绍 随着生成式预训练 Transformer (GPT) 的出现&#xff0c;技术世界正在见证范式转变。 这种人工智能驱动的创新不仅仅是一种转瞬即逝的趋势&#xff0c;而是一种趋势。 它已成为科技行业的基石&#xff0c…

PCA算法(Principal Component Analysis)揭秘

经典PCA算法 PCA算法的应用包括降维、有损数据压缩、特征抽取、数据可视化等。目前PCA算法有两个通用定义&#xff0c;能殊途同归&#xff0c;得到相同的结果。一方面&#xff0c;我们可以用正交投影来定义PCA&#xff0c;即将数据投影到更低维的线性子空间&#xff0c;也被称…

一文2700字使用 JMeter 进行灵活的接口自动化测试!

简介&#xff1a; JMeter 是一个开源的负载测试工具&#xff0c;它可以模拟多种协议和应用程序的负载&#xff0c;包括 HTTP、FTP、SMTP、JMS、SOAP 和 JDBC 等。在进行接口自动化测试时&#xff0c;使用 JMeter 可以帮助我们快速地构建测试用例&#xff0c;模拟多种场景&#…

Windows:IntelliJ IDEA Ultimate 安装 PHP 插件

在 IntelliJ IDEA Ultimate 中安装 PHP 插件&#xff0c;支持PHP开发调试 首先&#xff0c;进入File > Setting&#xff1a; 再次选择Plugins&#xff0c;然后选择上面的 Marketplace。 在搜索栏中输入 PHP&#xff0c;然后单击左侧的 Install 进行安装就可以了。 安装成功…

文档管理系统解决方案(word原件)

1.系统概述 1.1.需求描述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 数据备份技术 3.系统功能设计 3.1.功能清单列表 3.2.基础数据管理 3.3.位置管理 3.4.文档使用 3.5.文档管理 软件全套资料包获取方式①&#xff1a;软件项…

HarmonyOS实战开发DLP-如何实现一个安全类App。

介绍 本示例是一个安全类App&#xff0c;使用ohos.dlpPermission 接口展示了在eTS中普通文件加密受限的过程。 效果预览 使用说明: 1.启动应用后点击“”按钮可以添加一个普通文件; 2.长按点击加密按钮&#xff0c;出现加密权限弹窗&#xff0c;选择需要设置的权限并点击确定…

高效解决Ubuntu Server 18.04.1 LTS 64bit更新gdb8.1.1到gdb12.1

文章目录 问题解决步骤 问题 因为需要用到gdb一些指令&#xff0c;但是gdb8.x好像存在普遍的问题&#xff0c;实现不了某些指令&#xff0c;比方说set detach-on-fork on&#xff0c;升级版本也没有比较好的教程 经过我不断的试错&#xff0c;我终于升级成功了&#xff01;&a…

项目中 使用 spring cache redis 出现大量keys* 慢查询排查以及修复

前言 业务反馈 redis里有大量的慢查询 而且全是keys 的命令 排查 首先登录 阿里云查看redis的慢查询日志 如下 主要使用到redis cache的注解功能 分别是 CacheEvict 和 Cacheable 注意 CacheEvict 这个比较特殊 会进行驱逐缓存 说白就会删除缓存或者让缓存失效 第一时间想…

内网穿透的应用-如何使用Docker本地部署Dify LLM结合内网穿透实现公网访问本地开发平台

文章目录 1. Docker部署Dify2. 本地访问Dify3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 本文主要介绍如何在Linux Ubuntu系统以Docker的方式快速部署Dify,并结合cpolar内网穿透工具实现公网远程访问本地Dify&#xff01; Dify 是一款…

10款白嫖党必备的ai写作神器,你都知道吗? #媒体#人工智能#其他

从事自媒体运营光靠自己手动操作效率是非常低的&#xff0c;想要提高运营效率就必须要学会合理的使用一些辅助工具。下面小编就跟大家分享一些自媒体常用的辅助工具&#xff0c;觉得有用的朋友可以收藏分享。 1.飞鸟写作 这是一个微信公众号 面向专业写作领域的ai写作工具&am…

多叉树题目:子树中标签相同的结点数

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;子树中标签相同的结点数 出处&#xff1a;1519. 子树中标签相同的结点数 难度 5 级 题目描述 要求 给你一个树&#xff08;即一个连通的无向无环图…

2024年中国金融科技(FinTech)行业发展洞察报告

核心摘要&#xff1a; 金融监管体系的改革推动金融科技行业进入超级监管时代&#xff0c;数据要素应用与金融场景建设成为如今行业关注的重要领域&#xff0c;为金融机构提供以业务需求为导向的技术服务成为“厚积成势”阶段行业发展的新目标&#xff0c;市场参与者的“业技融…

峥嵘九载,逐云而上:青果乔迁新址,乘风破浪再起新篇

4月1日&#xff0c;近百名员工和诸多合作伙伴齐聚&#xff0c;共同见证了青果九周年庆典暨乔迁仪式这一里程碑式的时刻。 新起点&#xff0c;新征程&#xff0c;再启航&#xff01; 以新为序&#xff0c;共赴新征程 在典礼上&#xff0c;青果创始人和高管分别发表了致辞&#…

飞企互联-FE企业运营管理平台 druid路径 弱口令漏洞复现

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外,支持企业B2B、C2B与O2O等核心需求,为不同行业客户的互联网+转型提供支持。 0x02 漏洞概述 飞企互联-FE企业…