一、状态模式介绍
1. 解决的问题
次要解决在对象一个外部状态发生变化时,扭转其行为的问题。
2. 定义
状态模式是一种行为设计模式,让你能在一个对象的外部状态变动时扭转其行为,使其看上去就像扭转了本身所属的类一样。
3. 利用场景
- 如果对象须要依据本身以后状态进行不同行为,同时状态的数量十分多且与状态相干的代码会频繁变更的话,可应用状态模式。
- 如果某个类须要依据成员变量的以后值扭转本身行为,从而须要应用大量的条件语句时,可应用状态模式。
- 当类似状态和基于条件的状态机转换中存在许多反复代码时,可应用状态模式。
二、状态模式优缺点
1. 长处
- 繁多职责准则:将与特点状态相干的代码放在独自的类中。
- 开闭准则:无需批改已有状态类和上下文就能引入新状态。
- 通过打消臃肿的状态机条件语句简化上下文代码。
2. 毛病
- 如果状态机只有很少的几个状态,或者很少产生扭转,那么利用该模式可能会显得小题大做。
三、状态模式利用实例:简略高效的工夫治理——番茄工作法
1. 实例场景
不晓得大家有没有常常想认真学习,却始终晚会再说的状况,我反正就是。
最近发现了个番茄工作法,找了个软件体验了一下,听着滴答滴答的工作背景音效,还是很有种工夫在哗啦哗啦流的紧迫感,能肯定水平上进步点效率,当然可能听习惯了就不当回事了。
具体的软件如果想要的话,评论留言通知我。
番茄工作法是弗朗西斯科·西里洛在 1922 年创立的一种工夫治理办法,有助于进步工作效率,养成良好的学习习惯。
它的基本原理就是把工作工夫分为多个番茄钟,一个番茄钟由 25 分钟工作工夫和 5 分钟休息时间组成。
- 25 分钟的工作工夫内,要放弃专一,防止烦扰。
5 分钟的休息时间倡议来到工作区域,喝一杯茶,做一些简略的舒展静止。
这样看是不是还有点护眼,让咱们这些天天对着电脑的农民工能及时想起来本人的眼睛须要劳动。
很多时候,感觉忙了一天,也不晓得本人在忙啥,也能够用番茄工作法将本人的一天记录下来,剖析一下工夫都去哪了?
明天,就以番茄工作法的工作状态到劳动状态为例,介绍一下状态模式。
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();}
番茄-工作状态类
/** * 番茄-工作状态类 */@Slf4jpublic class WorkPomodoroState implements PomodoroState { /** * 工作 */ @Override public void work() { log.info("工作中:请放弃高度集中!"); } /** * 劳动 */ @Override public void rest() { log.info("工作状态中断:该番茄钟作废!"); }}
番茄-劳动状态类
/** * 番茄-劳动状态类 */@Slf4jpublic class RestPomodoroState implements PomodoroState { /** * 工作 */ @Override public void work() { log.info("良好的劳动才是下一个番茄钟开始的必要条件!"); } /** * 劳动 */ @Override public void rest() { log.info("工作工夫完结了,喝杯水,伸个懒腰,看看窗外!"); }}
2.2.2 服务类
番茄工作法服务接口
/** * 番茄工作法服务接口 */public interface PomodoroService { /** * 开启番茄 */ void openPomodoro();}
番茄工作法服务实现类
/** * 番茄工作法服务实现类 */@Slf4jpublic 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
四、状态模式构造
- 上下文(Context)保留了对于一个具体状态对象的援用,并会将所有与该状态相干的工作委派给它。上下文通过状态接口与状态对象交互,且会提供一个设置器用于传递新的状态对象。
- 状态(State)接口会申明特定于状态的办法,这些办法应能被其余所有具体状态所了解。
具体状态(Concrete States)会自行实现特定于状态的办法。为了防止多个状态中蕴含类似代码,能够提供一个封装有局部通用行为的两头抽象类。
状态对象可存储对于上下文对象的反向援用。状态能够通过该援用从上下文处获取所需信息,并且能触发状态转移。
- 上下文和具体状态都能够设置上下文的下个状态,并可通过替换连贯到上下文的状态对象来实现理论的状态转换。
设计模式并不难学,其自身就是多年教训提炼出的开发指导思想,关键在于多加练习,带着应用设计模式的思维去优化代码,就能构建出更正当的代码。
源码地址:https://github.com/yiyufxst/design-pattern-java
参考资料:
小博哥重学设计模式:https://github.com/fuzhengwei/itstack-demo-design
深刻设计模式:https://refactoringguru.cn/design-patterns/catalog