设计模式(三)- 状态模式

toc

#状态模式

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

在平常开发自己也会遇到好多方法过长,里面的判断语句太多,导致后续修改十分麻烦。今天看到状态模式的介绍,觉得很受益。下面通过一段代码错误的显示一遍没有使用状态模式的代码

public class Work {
    private int hour;
    private boolean finished;
    private boolean taskFinished;
    
    public void workProgram() {
        if (hour < 12) {
            System.out.println("current time: "+new Date() + "  working in the morning");
        } else if (hour < 13) {
            System.out.println("current time: "+new Date() + "  have a break!");
        } else if (hour < 17) {
            System.out.println("current time: "+new Date() + "  working in the afternoon");
        } else {
            if (finished) {
                System.out.println("current time: "+new Date() + " after work!");
            } else if (hour <12) {
                System.out.println("current time: "+new Date() + "  very hard!");
            }
        }
    }
    
}
从上述代码中看出,当我要修改hour的判断范围,或者在各个判断条件之后新增一些功能,都会使这段方法变得十分长,而且阅读起来也比较繁琐。
所以代码过长了就有坏味道了。在面向对象的设计中也希望做到代码的责任分解。

当一个对象状态转换的条件表达式过于复杂的时候,把状态的判断逻辑移到不同的一系列类当中,可以把复杂的判断逻辑简单化,这就是状态模式的主要作用。但并不是所有有判断的都要使用状态模式,简单的判断逻辑就不需要了。

代码改良

/**
 * 工作类 没有了判断语句
 */
public class Work {
    private int hour;

    private boolean finished;

    private boolean taskFinished;

    private State state;

    private State currentState;

    public Work() {
        currentState = new ForenoonState();

    }

    public void workProgram() {
        currentState.workProgram(this);
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    public boolean isFinished() {
        return finished;
    }

    public void setFinished(boolean finished) {
        this.finished = finished;
    }

    public boolean isTaskFinished() {
        return taskFinished;
    }

    public void setTaskFinished(boolean taskFinished) {
        this.taskFinished = taskFinished;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.currentState = state;
    }
}

/**
 * morning
 */
public class ForenoonState extends State {
    public void workProgram(Work work) {
        if (work.getHour() < 12) {
            System.out.println("current time: "+new Date() + "  working in the morning");
        } else {
            work.setState(new NoonState());
        }
    }
}

/**
 * noon
 */
public class NoonState extends State {
    public void workProgram(Work work) {
        if (work.getHour() < 13) {
            System.out.println("current time: "+new Date() + "  have a break!");
        } else {
            work.setState(new AfternoonState());
        }
    }
}

/**
 * afternoon
 */
public class AfternoonState extends State {
    public void workProgram(Work work) {
        if (work.getHour() < 17) {
            System.out.println("current time: "+new Date() + "  working in the afternoon");
        } else {
            //todo .......
        }
    }
}

/**
 * Client
 */
public class Client {

    public static void main(String[] args) {
        Work work = new Work();
        work.setHour(12);
        work.workProgram();

        work.setHour(13);
        work.workProgram();
    }
}
image.png

从上术代码中,在客户端代码不需要做任何的修改,程序可以变得非常灵活,当程序还需要添加一个额外的工作状态时,再添加一个其它状态类的代码,也不影响其它状态类的代码。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

仿qq聊天及定位等

聊天其实就是要实现消息推送,而推送消息就需要保持连接(长连接)。在之前项目里虽然实现了即时聊天,但是一种很本的方法。 去掉了其中的网络访问。地图试用的百度AP...

1726
来自专栏小狼的世界

IE下JS文件失效问题总结

今天遇到了一个很诡异的问题,Firefox下好好的页面,在IE下却接二连三的报错,这到底是什么地方产生的错误。

873
来自专栏坚毅的PHP

redis学习笔记

摘录些nosqlfans上看的资源(http://blog.nosqlfan.com/html/3537.html),用了一年了,只会安装、启动和get set...

35610
来自专栏Hongten

Java Web servlet与cookie

在C:\Documents and Settings\Administrator\Cookies目录下面会有一个   hongten@webproject_co...

693
来自专栏PHP技术

PHP的PSR系列规范都有啥内容

PSR 是PHP Standard Recommendation的简写,它其实应该叫PSRs,即系列推荐标准:目前通过的规范有PSR-0(Autoloadin...

3257
来自专栏我的博客

Tp3.1.2模型学习

1.模型定义 命名规则是除去表前缀的数据表名称,采用驼峰命名,并且首字母大写,然后加上后缀Model 其中tableName是不包含表前缀的数据表名称,一般用...

3154
来自专栏Golang语言社区

golang-xorm库快速学习

xorm xorm是一个Go语言ORM库. 通过它可以使数据库操作非常简便. 全部文档点我 用法入门: 前提:定义本文中用到的struct和基本代码如下 // ...

5628
来自专栏python3

习题23:更多更多的练习

1 在第一行执行了import lianxi_23 ,和你之前做过的一样,import导入一个模块,而我们写的lianxi_23.py就是一个模块,注意导入模块...

642
来自专栏osc同步分享

mybatis 的一些常用功能

1. association 查询结果的一对一关联: <resultMap id="blogResult" type="Blog"> <id propert...

2648
来自专栏木木玲

Netty 源码解析 ——— AdaptiveRecvByteBufAllocator

2042

扫码关注云+社区