设计模式-状态模式
状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在内部状态发生改变时,改变其行为。状态模式将状态的逻辑封装到独立的状态类中,避免了使用大量的条件语句(如 if-else
或 switch-case
),从而使代码更加清晰、灵活和可扩展。
状态模式的组成部分:
- 上下文(Context):
- 定义了客户端所需要的接口,并维护一个当前状态的引用,用于切换状态。
- 抽象状态(State):
- 定义了一个接口,封装与上下文相关的行为。
- 具体状态(ConcreteState):
- 实现了抽象状态的具体行为,每个类代表一种状态,并负责实现与该状态相关的行为。
示例代码:文档审批流程
问题背景
假设有一个文档审批系统,文档的状态有以下几种:
- 草稿状态(Draft):可以编辑和提交。
- 审核中状态(UnderReview):只能撤回。
- 发布状态(Published):无法编辑或提交。
文档的行为(如编辑、提交、撤回等)会根据当前状态的不同而表现出不同的行为。
实现代码
// 抽象状态
interface State {
void edit(Document context); // 编辑文档
void submit(Document context); // 提交文档
void revoke(Document context); // 撤回文档
}
// 具体状态:草稿状态
class DraftState implements State {
@Override
public void edit(Document context) {
System.out.println("文档正在编辑...");
}
@Override
public void submit(Document context) {
System.out.println("文档已提交,进入审核状态。");
context.setState(new UnderReviewState());
}
@Override
public void revoke(Document context) {
System.out.println("草稿状态下无法撤回文档!");
}
}
// 具体状态:审核中状态
class UnderReviewState implements State {
@Override
public void edit(Document context) {
System.out.println("审核中,无法编辑文档!");
}
@Override
public void submit(Document context) {
System.out.println("文档已提交,不能重复提交!");
}
@Override
public void revoke(Document context) {
System.out.println("审核中,文档已撤回到草稿状态。");
context.setState(new DraftState());
}
}
// 具体状态:发布状态
class PublishedState implements State {
@Override
public void edit(Document context) {
System.out.println("文档已发布,无法编辑!");
}
@Override
public void submit(Document context) {
System.out.println("文档已发布,无法提交!");
}
@Override
public void revoke(Document context) {
System.out.println("文档已发布,无法撤回!");
}
}
// 上下文类:文档
class Document {
private State state; // 当前状态
public Document() {
// 初始状态为草稿
this.state = new DraftState();
}
public void setState(State state) {
this.state = state;
}
// 调用当前状态的方法
public void edit() {
state.edit(this);
}
public void submit() {
state.submit(this);
}
public void revoke() {
state.revoke(this);
}
}
// 客户端
public class StatePatternExample {
public static void main(String[] args) {
Document document = new Document();
// 草稿状态
document.edit();
document.submit();
// 审核中状态
document.edit();
document.revoke();
// 回到草稿状态
document.edit();
document.submit();
// 审核中状态提交成功
document.submit();
// 发布状态
document.revoke();
}
}
输出结果:
文档正在编辑...
文档已提交,进入审核状态。
审核中,无法编辑文档!
审核中,文档已撤回到草稿状态。
文档正在编辑...
文档已提交,进入审核状态。
文档已提交,不能重复提交!
文档已发布,无法撤回!
状态模式的优点:
- 清晰的状态转换:
- 将状态逻辑封装在独立的状态类中,避免了在上下文类中使用复杂的条件语句。
- 扩展性强:
- 可以轻松添加新的状态或修改现有状态,而无需修改上下文类的代码。
- 符合单一职责原则:
- 每个状态类只关注与其对应的状态相关的行为。
状态模式的缺点:
- 增加了类的数量:
- 每个状态都需要定义一个类,可能导致类的数量增加。
- 状态之间的耦合性:
- 状态类之间可能需要切换状态,这会引入一定的耦合性。
状态模式的适用场景:
- 对象的行为依赖于状态,并且状态会在运行时发生改变。
- 避免条件语句(如
if-else
或switch-case
)导致代码复杂度增加。 - 希望通过改变状态来改变对象行为,而不影响对象的其他部分。
状态模式常用于工作流系统、游戏角色状态管理、设备操作状态等场景中。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)