初学 Java 设计模式(二十):实战状态模式 「亲身实践,简单高效的时间管理——番茄工做法」

1、状态模式介绍

1. 解决的问题

主要解决在对象一个内部状态发生变化时,改变其行为的问题。java

2. 定义

状态模式是一种行为设计模式,让你能在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类同样。git

3. 应用场景

  • 若是对象须要根据自身当前状态进行不一样行为,同时状态的数量很是多且与状态相关的代码会频繁变动的话,可以使用状态模式。
  • 若是某个类须要根据成员变量的当前值改变自身行为,从而须要使用大量的条件语句时,可以使用状态模式。
  • 当类似状态和基于条件的状态机转换中存在许多重复代码时,可以使用状态模式。

2、状态模式优缺点

1. 优势

  • 单一职责原则:将与特色状态相关的代码放在单独的类中。
  • 开闭原则:无需修改已有状态类和上下文就能引入新状态。
  • 经过消除臃肿的状态机条件语句简化上下文代码。

2. 缺点

  • 若是状态机只有不多的几个状态,或者不多发生改变,那么应用该模式可能会显得小题大作。

3、状态模式应用实例:简单高效的时间管理——番茄工做法

1. 实例场景

不知道你们有没有常常想认真学习,却一直晚会再说的状况,我反正就是。github

最近发现了个番茄工做法,找了个软件体验了一下,听着滴答滴答的工做背景音效,仍是颇有种时间在哗啦哗啦流的紧迫感,能必定程度上提升点效率,固然可能听习惯了就不当回事了。设计模式

具体的软件若是想要的话,评论留言告诉我。ide

番茄工做法是弗朗西斯科·西里洛在 1922 年建立的一种时间管理方法,有助于提升工做效率,养成良好的学习习惯。学习

它的基本原理就是把工做时间分为多个番茄钟,一个番茄钟由 25 分钟工做时间和 5 分钟休息时间组成。测试

  • 25 分钟的工做时间内,要保持专一,避免干扰。
  • 5 分钟的休息时间建议离开工做区域,喝一杯茶,作一些简单的伸展运动。优化

    这样看是否是还有点护眼,让咱们这些每天对着电脑的农民工能及时想起来本身的眼睛须要休息。设计

不少时候,感受忙了一天,也不知道本身在忙啥,也能够用番茄工做法将本身的一天记录下来,分析一下时间都去哪了?rest

今天,就以番茄工做法的工做状态到休息状态为例,介绍一下状态模式。

2. 状态模式实现

2.1 工程结构
state-pattern
└─ src
    ├─ main
    │    └─ java
    │    └─ org.design.pattern.state
    │       ├─ model
    │       │    ├─ PomodoroState.java
    │       │    └─ impl
    │       │        ├─ WorkPomodoroState.java
    │       │        └─ RestPomodoroState.java
    │       └─ service
    │            ├─ PomodoroService.java
    │            └─ impl
    │                 └─ PomodoroServiceImpl.java
    └─ test
        └─ java
            └─ org.design.pattern.state.test
                  └─ PomodoroTest.java
2.2 代码实现
2.2.1 实体类

番茄状态接口

/**
 * 番茄状态接口
 */
public interface PomodoroState {

    /**
     * 工做
     */
    void work();

    /**
     * 休息
     */
    void rest();
}

番茄-工做状态类

/**
 * 番茄-工做状态类
 */
@Slf4j
public class WorkPomodoroState implements PomodoroState {

    /**
     * 工做
     */
    @Override
    public void work() {
        log.info("工做中:请保持高度集中!");
    }

    /**
     * 休息
     */
    @Override
    public void rest() {
        log.info("工做状态中断:该番茄钟做废!");
    }
}

番茄-休息状态类

/**
 * 番茄-休息状态类
 */
@Slf4j
public class RestPomodoroState implements PomodoroState {

    /**
     * 工做
     */
    @Override
    public void work() {
        log.info("良好的休息才是下一个番茄钟开始的必要条件!");
    }

    /**
     * 休息
     */
    @Override
    public void rest() {
        log.info("工做时间结束了,喝杯水,伸个懒腰,看看窗外!");
    }
}
2.2.2 服务类

番茄工做法服务接口

/**
 * 番茄工做法服务接口
 */
public interface PomodoroService {

    /**
     * 开启番茄
     */
    void openPomodoro();
}

番茄工做法服务实现类

/**
 * 番茄工做法服务实现类
 */
@Slf4j
public class PomodoroServiceImpl implements PomodoroService {

    /**
     * 开启一次番茄
     */
    @Override
    public void openPomodoro() {
        // 番茄-工做时间
        PomodoroState workState = new WorkPomodoroState();
        log.info("开启一次番茄时间");
        workState.work();
        log.info("工做时间想休息");
        workState.rest();
        log.info("工做时间结束");
        // 番茄-休息时间
        PomodoroState restState = new RestPomodoroState();
        restState.rest();
        log.info("休息时间想工做");
        restState.work();
        log.info("休息时间结束,准备好开始下一个番茄了嘛?");
     }
}
2.3 测试验证
2.3.1 测试验证类
/**
 * 番茄工做法测试类
 */
public class PomodoroTest {

    @Test
    public void test() {
        PomodoroService pomodoroService = new PomodoroServiceImpl();
        pomodoroService.openPomodoro();
    }
}
2.3.2 测试结果
15:07:06.447 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 开启一次番茄时间
15:07:06.449 [main] INFO  o.d.p.s.model.impl.WorkPomodoroState - 工做中:请保持高度集中!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 工做时间想休息
15:07:06.449 [main] INFO  o.d.p.s.model.impl.WorkPomodoroState - 工做状态中断:该番茄钟做废!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 工做时间结束
15:07:06.449 [main] INFO  o.d.p.s.model.impl.RestPomodoroState - 工做时间结束了,喝杯水,伸个懒腰,看看窗外!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 休息时间想工做
15:07:06.449 [main] INFO  o.d.p.s.model.impl.RestPomodoroState - 良好的休息才是下一个番茄钟开始的必要条件!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 休息时间结束,准备好开始下一个番茄了嘛?

Process finished with exit code 0

4、状态模式结构

状态模式-模式结构图

  1. 上下文(Context)保存了对于一个具体状态对象的引用,并会将全部与该状态相关的工做委派给它。上下文经过状态接口与状态对象交互,且会提供一个设置器用于传递新的状态对象。
  2. 状态(State)接口会声明特定于状态的方法,这些方法应能被其余全部具体状态所理解。
  3. 具体状态(Concrete States)会自行实现特定于状态的方法。为了不多个状态中包含类似代码,能够提供一个封装有部分通用行为的中间抽象类。

    状态对象可存储对于上下文对象的反向引用。状态能够经过该引用从上下文处获取所需信息,而且能触发状态转移。

  4. 上下文和具体状态均可以设置上下文的下个状态,并可经过替换链接到上下文的状态对象来完成实际的状态转换。

设计模式并不难学,其自己就是多年经验提炼出的开发指导思想,关键在于多加练习,带着使用设计模式的思想去优化代码,就能构建出更合理的代码。

源码地址:https://github.com/yiyufxst/design-pattern-java

参考资料:
小博哥重学设计模式:https://github.com/fuzhengwei/itstack-demo-design
深刻设计模式:https://refactoringguru.cn/design-patterns/catalog

相关文章
相关标签/搜索