设计模式之状态模式详解(定义、优缺点、应用场景、实例类图)
时间:2024-12-09
来源:互联网
在状态模式(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教程栏目。
-
WebStorm干嘛用的 WebStorm和VSCode哪个好用 时间:2025-09-13
-
PyCharm详细的安装及使用教程 时间:2025-09-13
-
PyCharm是干什么用的 PyCharm和Python的区别 时间:2025-09-13
-
PHP运行环境的搭建方法及流程详解 时间:2025-09-13
-
PHPstorm环境配置与应用 PHPstorm怎么配置PHP环境 时间:2025-09-13
-
PHP date()函数详解(定义、语法、用法) 时间:2025-09-13
今日更新
-
天天鉴宝的梗是什么梗 揭秘网友疯狂玩梗背后的搞笑真相
阅读:18
-
天天生气跺脚梗是网络热梗,指暴躁又可爱的抓狂表情包,网友疯狂模仿超解压!
阅读:18
-
天天是什么梗?揭秘网络热词天天的爆火原因和趣味用法
阅读:18
-
天天玩老梗是什么梗?揭秘网络热梗反复刷屏现象,年轻人为何越玩越上头
阅读:18
-
天天玩冷战梗是什么梗 揭秘情侣间冷战互怼的幽默网络热词
阅读:18
-
天天向上的梗是什么梗?揭秘年轻人最爱用的正能量热梗来源和用法
阅读:18
-
未定事件簿予爱未名·莫弈篇-生日拼图限时活动即将开启
阅读:18
-
忘川风华录幽墟五-幽墟五文曲应该怎么配队
阅读:18
-
奇迹暖暖琉璃异境复刻开启-完成任务可获得丰富奖励
阅读:18
-
如鸢月海夜航船第四夜-34级紫人鱼赤儒涔机制
阅读:18