- 一、导语
- 二、怎么用
1.样例背景
2.UML类图
3.代码示例- 三、优缺点
- 四、使用场景
1.概括描述
2.现存知名产品中的使用示例- 五、与其他设计模式的对比
- 六、参考
一、导语
状态模式(State),容许一个对象在其内部状态改变时,改变他的行为(当然不改变他的行为,只做状态的转换,也是可以的)。
一定长度上可以简化 if/else 分支带来的麻烦。
二、怎么用
共有2个示例,代码详见访问链接
下面以example2举例说明
1. 样例背景
模拟程序员一天中不同状态的切换
工作时通常有如下状态:
1.上午状态
2.中午状态
3.下午状态
4.傍晚状态
5.加班状态
6.猝死状态
(注:该代码有执行顺序的要求,仅做示例)
2. UML类图
WorkState ------------------- 状态抽象类
XxxxState ---------------- 具体的状态类
Work ----------------------------- 模拟具体的工作情况的类
3. 代码示例
/**
* description: 工作状态抽象类
*/
public abstract class WorkState {
abstract void programming(Work work);
}
/**
* description: 上午状态
*/
public class MorningState extends WorkState {
@Override
void programming(Work work) {
if (work.getHour() < 12 && work.getHour() >= 9) {
System.out.println(
String.format("当前时间为: %s,精神状态很好,效率很高!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 超过12点,转入中午工作状态
work.setWorkState(new NoonState());
work.programming();
}
}
}
/**
* description: 中午工作状态
*/
public class NoonState extends WorkState {
@Override
void programming(Work work) {
if (work.getHour() < 14 && work.getHour() >= 12) {
System.out.println(
String.format("当前时间为: %s,刚吃饱,有点困!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 超过14点,转入下午工作状态
work.setWorkState(new AfterNoonState());
work.programming();
}
}
}
/**
* description: 下午工作状态
*/
public class AfterNoonState extends WorkState {
@Override
void programming(Work work) {
if (work.getHour() < 17 && work.getHour() >= 14) {
System.out.println(
String.format("当前时间为: %s,中午没睡,有点疲倦,效率不高!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 超过17点,转入傍晚工作状态
work.setWorkState(new EveningState());
work.programming();
}
}
}
/**
* description: 傍晚工作状态
*/
public class EveningState extends WorkState {
@Override
void programming(Work work) {
if (work.getHour() < 19 && work.getHour() >= 17) {
System.out.println(
String.format("当前时间为: %s,快到晚饭时间了,有点饿了!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 超过19点,转入加班工作状态
work.setWorkState(new WorkOvertimeState());
work.programming();
}
}
}
/**
* description: 加班工作状态
*/
public class WorkOvertimeState extends WorkState {
@Override
void programming(Work work) {
if (work.getHour() < 22 && work.getHour() >= 19) {
System.out.println(
String.format("当前时间为: %s,领导不让下班,非给找点活!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 超过22点,转入猝死工作状态
work.setWorkState(new SuddenDeathState());
work.programming();
}
}
}
/**
* description: 猝死工作状态
*/
public class SuddenDeathState extends WorkState {
@Override
void programming(Work work) {
if ((work.getHour() < 24 && work.getHour() >= 22)
|| (work.getHour() < 4 && work.getHour() >= 0)){
System.out.println(
String.format("当前时间为: %s,要猝死了!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}else { // 转入猝死状态
System.out.println(
String.format("当前时间为: %s,发现人已猝死!—— 【 %s 】",
work.getHour(), work.getWorkState().getClass().getSimpleName()));
}
}
}
/**
* description: 客户端测试类
* todo 注: 该代码有执行顺序的要求,仅做示例
*/
public class Test {
public static void main(String[] args) {
Work work = new Work();
work.setHour(10);
work.programming();
System.out.println();
work.setHour(13);
work.programming();
System.out.println();
work.setHour(15);
work.programming();
System.out.println();
work.setHour(18);
work.programming();
System.out.println();
work.setHour(21);
work.programming();
System.out.println();
work.setHour(6);
work.programming();
System.out.println();
work.setHour(10);
work.programming();
System.out.println();
}
}
运行结果
当前时间为: 10.0,精神状态很好,效率很高!—— 【 MorningState 】
当前时间为: 13.0,刚吃饱,有点困!—— 【 NoonState 】
当前时间为: 15.0,中午没睡,有点疲倦,效率不高!—— 【 AfterNoonState 】
当前时间为: 18.0,快到晚饭时间了,有点饿了!—— 【 EveningState 】
当前时间为: 21.0,领导不让下班,非给找点活!—— 【 WorkOvertimeState 】
当前时间为: 6.0,发现人已猝死!—— 【 SuddenDeathState 】
当前时间为: 10.0,发现人已猝死!—— 【 SuddenDeathState 】
三、优缺点
缺点
1.状态多的业务场景导致累的数目增加,系统变复杂优点
1.将不同状态隔离
2.把各种状态的转换逻辑,分不到State的子类中,减少相互间的依赖
3.增加新的状态非常简单
四、使用场景
1. 概括描述
- 它主要解决的是,当控制一个对象状态转换的过程(比如判断条件)比较复杂时,我们可以把状态的判断逻辑,放到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。换句话说,可以理解为当一个对象的行为取决于他的状态,并且他必须在运行时根据他的状态改变他的行为时,就可以考虑使用状态模式了。
2. 现存知名产品中的使用示例 todo
2.1 javax.faces.lifecycle (jsf)
五、相关设计模式
1. 状态模式与享元模式
在一些状态对象可复用的地方,他们有时候时可以配合起来一起使用的。