设计模式之状态模式详解(定义、优缺点、应用场景、实例类图)
在状态模式(State Pattern)中,类的行为是基于它的状态改变的,这种类型的设计模式属于行为型模式。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。状态模式允许对象在内部状态改变时改变其行为,使得对象在不同的状态下有不同的行为表现。通过将每个状态封装成独立的类,可以避免使用大量的条件语句来实现状态切换。
一、状态模式的介绍
意图
允许一个对象在其内部状态改变时改变其行为,看起来就像是改变了其类一样。
主要解决的问题
状态模式解决对象行为依赖于其状态的问题,使得对象可以在状态变化时切换行为。
使用场景
当代码中存在大量条件语句,且这些条件语句依赖于对象的状态时。
实现方式
定义状态接口:声明一个或多个方法,用于封装具体状态的行为。
创建具体状态类:实现状态接口,根据状态的不同实现具体的行为。
定义上下文类:包含一个状态对象的引用,并在状态改变时更新其行为。
关键代码
状态接口:声明行为方法。
具体状态类:实现状态接口,封装具体行为。
上下文类:维护一个状态对象,并提供方法以改变其状态。
结构
状态模式包含以下几个主要角色:
上下文(Context):定义了客户感兴趣的接口,并维护一个当前状态对象的引用。上下文可以通过状态对象来委托处理状态相关的行为。
状态(State):定义了一个接口,用于封装与上下文相关的一个状态的行为。
具体状态(Concrete State):实现了状态接口,负责处理与该状态相关的行为。具体状态对象通常会在内部维护一个对上下文对象的引用,以便根据不同的条件切换到不同的状态。
应用实例
篮球运动员状态:运动员可以有正常、不正常和超常等状态。
曾侯乙编钟:编钟作为上下文,不同的钟(状态)有不同的演奏效果。
二、状态模式的优缺点
优点
封装状态转换规则:将状态转换逻辑封装在状态对象内部。
易于扩展:增加新的状态类不会影响现有代码。
集中状态相关行为:将所有与特定状态相关的行为集中到一个类中。
简化条件语句:避免使用大量的条件语句来切换行为。
状态共享:允许多个上下文对象共享同一个状态对象。
缺点
增加类和对象数量:每个状态都需要一个具体的状态类。
实现复杂:模式结构和实现相对复杂。
开闭原则支持不足:增加新状态或修改状态行为可能需要修改现有代码。
三、状态模式的使用建议
当对象的行为随状态改变而变化时,考虑使用状态模式。
状态模式适用于替代复杂的条件或分支语句。
状态模式适用于状态数量有限(通常不超过5个)的情况。
谨慎使用,以避免系统变得过于复杂。
四、状态模式的实现
我们将创建一个 State 接口和实现了 State 接口的实体状态类。Context 是一个带有某个状态的类。
StatePatternDemo,我们的演示类使用 Context 和状态对象来演示 Context 在状态改变时的行为变化。

步骤 1:创建一个接口。
State.java
publicinterfaceState{
publicvoiddoAction(Contextcontext);
}步骤 2:创建实现接口的实体类。
StartState.java
publicclassStartStateimplementsState{
publicvoiddoAction(Contextcontext){
System.out.println("Playerisinstartstate");
context.setState(this);
}
publicStringtoString(){
return"StartState";
}
}StopState.java
publicclassStopStateimplementsState{
publicvoiddoAction(Contextcontext){
System.out.println("Playerisinstopstate");
context.setState(this);
}
publicStringtoString(){
return"StopState";
}
}步骤 3:创建 Context 类。
Context.java
publicclassContext{
privateStatestate;
publicContext(){
state=null;
}
publicvoidsetState(Statestate){
this.state=state;
}
publicStategetState(){
returnstate;
}
}步骤 4:使用 Context 来查看当状态 State 改变时的行为变化。
StatePatternDemo.java
publicclassStatePatternDemo{
publicstaticvoidmain(String[]args){
Contextcontext=newContext();
StartStatestartState=newStartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopStatestopState=newStopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}步骤 5:执行程序,输出结果:
Playerisinstartstate
StartState
Playerisinstopstate
StopState
以上就是php小编整理的全部内容,希望对您有所帮助,更多相关资料请查看php教程栏目。
-
什么是VoIP?它是如何工作的?VoIP的工作原理 时间:2025-11-07 -
MPEG-4是什么格式 MPEG-4和MP4的区别 时间:2025-11-07 -
什么是OAuth OAuth2.0认证原理和流程 OAuth2.0授权机制 时间:2025-11-07 -
什么是IMAP协议 IMAP协议和POP3协议的区别 时间:2025-11-07 -
什么是最大传输单元(MTU) 最大传输单元设置多少合适 时间:2025-11-07 -
什么是云存储 云存储的优势和应用场景 云存储有哪些类型 云存储如何工作 时间:2025-11-07
今日更新
-
2025年稳定币信任度排行:USDT、USDC与DAI三大首选币种解析
阅读:18
-
愚人节是什么梗 揭秘整蛊狂欢背后的网络热梗真相
阅读:18
-
2025全球顶级DEX推荐:Uniswap PancakeSwap SushiSwap性能解析
阅读:18
-
2025年机构重仓数字货币投资指南:BTC、ETH、LINK领衔榜单
阅读:18
-
什么节奏是什么梗?揭秘网络热词背后的爆笑真相,3秒get流行密码!
阅读:18
-
天刀手游玄素鸿蒙外观上线-天气动作蜃镜裂世震撼登场
阅读:18
-
忘川风华录名士墨子技能详细-墨子怎么培养
阅读:18
-
2025三大潜力黑马币:SUI ENA ARB爆发式增长预测
阅读:18
-
王者荣耀最新英雄调整发布-花木兰增强元辅助全面升级
阅读:18
-
明日方舟:终末地帝江号概况-干员进驻舱室参考
阅读:18










