设计模式之状态模式
时间:2021-09-06
本文章向大家介绍设计模式之状态模式,主要包括设计模式之状态模式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
类似于我们商城下单,订单有各种状态,不同的状态下可以执行不同的操作。
结构
- State,状态接口,用来封装与上下文的一个特定状态所对应的行为。
- ConcreteState,具体状态实现类,提供对应状态的具体行为处理。
- Context,上下文,内部维护一个当前状态,并负责具体状态的切换。
简单实现
状态接口
public interface State {
void handle(Context context);
}
具体状态实现类
public class ConcreteStateA implements State {
@Override
public void handle(Context context) {
System.out.println("当前状态:A");
//状态 A 执行完后,迁移到状态 B
context.setState(new ConcreteStateB());
}
}
另一个具体状态实现
public class ConcreteStateB implements State {
@Override
public void handle(Context context) {
System.out.println("当前状态:B");
//状态 B 执行完后,迁移到状态 A
context.setState(new ConcreteStateA());
}
}
上下文
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void handle() {
// 注意:这里传入当前对象
state.handle(this);
}
public State getState() {
return state;
}
public Context setState(State state) {
this.state = state;
return this;
}
}
客户端
public class Client {
public static void main(String[] args) {
Context context = new Context(new ConcreteStateA());
context.handle();
context.handle();
context.handle();
context.handle();
context.handle();
}
}
状态模式在JSF中的实现
JSF 是一种用于构建Java Web 应用程序的标准框架。
JSF中的FacesContext,PhaseId
public class PhaseId implements Comparable {
...
private static final PhaseId[] values = {
ANY_PHASE, // 任意一个生命周期阶段
RESTORE_VIEW, // 恢复视图阶段
APPLY_REQUEST_VALUES, // 应用请求值阶段
PROCESS_VALIDATIONS, // 处理输入校验阶段
UPDATE_MODEL_VALUES, // 更新模型的值阶段
INVOKE_APPLICATION, // 调用应用阶段
RENDER_RESPONSE // 显示响应阶段
};
...
}
FacesContext中保存一个阶段对象
public class FacesContextImpl extends FacesContext {
private PhaseId currentPhaseId;
}
总结
优点
- 简化应用逻辑控制,使用单独的类来封装一个状态的处理,分离了状态和行为的处理。
- 更好的扩展性,很容易新增状态类的实现。
缺点
- 一个状态对应一个状态处理类,会导致类的数量过多,程序复杂。
本质
状态模式的本质是根据状态来分离和选择行为,通过接口分离了状态和行为,通过上下文来选择行为。
使用场景
- 一个对象的行为取决于它的状态,并且必须在运行时根据状态来改变它的行为。
- 一个操作中包含大量的分支语句,且这些分支依赖于该对象的状态,可以将各分支的处理封装到单独的状态处理类中。
参考
大战设计模式【14】—— 状态模式
设计模式——状态模式
状态模式(详解版)
设计模式(二十二)——状态模式(APP抽奖活动+借贷平台源码剖析)
研磨设计模式-书籍
原文地址:https://www.cnblogs.com/strongmore/p/15235691.html
- 内部类
- 初学java之接口基础
- java之内部类
- html学习第一讲(内容html常规控件的的使用)
- uva----(10794) A Different Task
- uva-----(11384)Help is needed for Dexter
- uva------(11464)Even Parity
- java SE学习之线程同步(详细介绍)
- java多线程的常用方法(以及注意事项)
- MFC学习之窗口基础
- java多线程下如何调用一个共同的内存单元(调用同一个对象)
- java之多线程(Thread)
- HDUOJ------3336 Count the string(kmp)
- hduoj------2594 Simpsons’ Hidden Talents
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux使用join -a1来合并两个文件
- ZFS是什么?使用ZFS的理由及特性介绍
- centos7.x 部署主、从DNS服务器问题
- Linux查看History记录加时间戳的小技巧
- Trash-Cli:Linux上的命令行回收站工具
- Linux中的tcpdump命令示例详解
- Linux系统文件的默认权限和特殊权限
- 如何判断一个对象是不是数组
- Linux使用NetworkManager随机生成你的MAC地址
- CentOS6.5下搭建文件共享服务Samba的教程
- ES5中的继承
- Linux定时自动删除旧垃圾文件的Autotrash工具
- Thinking in DAX with PowerBI - 逻辑框架 - 计算逻辑
- Linux并发执行很简单,这么做就对了
- 一条命令让你明白shell中read命令的常用参数