多字段驱动行为变更场景下State Pattern(状态模式)合理使用咨询
关于状态模式使用问题的解答
1. 当前用法是否属于对State Pattern的误用?
不算完全误用,但属于对状态模式适用场景的错配。
状态模式的核心设计目标是将状态相关的行为封装到独立的状态类中,且状态流转的逻辑由状态自身控制,避免Context类中出现大量和状态判断相关的分支代码。
你当前的用法符合「将行为委托给状态类处理」的基本要求,但问题在于:你把x、y两个业务字段和状态强绑定,且状态切换的逻辑完全散落在Context的各个修改x/y的入口中,没有达到状态模式想要消除分支逻辑散列的目标,反而引入了冗余代码。
2. 该场景下能否正确应用State Pattern并消除冗余判断?
完全可以,可按以下两个层级优化:
第一步:先消除重复的条件判断
将x、y到State实例的映射逻辑抽成独立的私有方法,所有修改x/y的地方统一调用该方法更新状态即可:
private void updateState() { if (x == 1 && y == 1) { xyState = new XY(); } else if (x == 1 && y == 0) { xyState = new X(); } else if (x == 0 && y == 1) { xyState = new Y(); } else { xyState = new Nothing(); } }
之后构造函数、setX()、setY()中修改完字段值后,直接调用updateState()即可,不需要重复写判断逻辑。
第二步:彻底消除条件分支,符合状态模式设计初衷
你当前的状态切换是由外部修改x/y触发的,要符合状态模式的标准设计,可以做如下改造:
- 定义State接口时,新增和x、y修改相关的方法,所有对x、y的修改都通过状态实例来完成,由状态类自己判断修改后要切换到什么状态
- 把x、y字段封装到Context中,提供给状态类读写的接口,外部不再直接调用setX、setY,而是调用Context暴露的修改x/y的方法,再委托给当前状态类处理
这样Context中就不会存在任何状态判断的分支代码,所有状态流转逻辑都内聚在各个状态实现类中,完全符合状态模式的设计要求。
另外如果你的x、y取值只有0和1两种固定组合,也可以用静态查表的方式消除分支:提前初始化一个key为(x,y)二元组、value为对应State单例的静态Map,updateState()时直接根据当前x、y的值查表获取对应的状态实例即可,不需要写任何if-else分支。
补充说明:如果你的业务场景中只有
print()这一个方法需要根据x/y的组合调整行为,状态模式的收益其实很低,反而会增加类的数量。只有当后续有多组方法都需要跟随x/y的组合变更行为时,状态模式的优势才会体现出来。
内容的提问来源于stack exchange,提问作者Mohammad Mehdi Sarfejoo
相关产品推荐
相关产品推荐

