策略模式中变量由客户端显式控制,代表可插拔算法;状态模式中变量由内部状态驱动,承载语义依赖与行为约束。

策略模式和状态模式在变量逻辑上的根本差异,不在于代码长什么样,而在于“谁控制变量”以及“变量代表什么”。
变量归属与生命周期不同
策略模式中的策略变量(如 paymentStrategy 或 formatter)由客户端显式设置并长期持有,属于上下文(Context)的配置项,生命周期由外部管理。它像一个可插拔的工具——换哪个,取决于当前业务规则或用户选择。
- 变量值通常由调用方决定(例如:用户选微信支付,系统就 setStrategy(new WechatPay()))
- 变量本身不记录历史、不感知上下文变化,也不触发自身更新
- 多个 Context 实例可共享同一个策略对象(策略易复用)
状态变量隐含转换逻辑
状态模式中的状态变量(如 currentState)是对象内在属性,其变更不是由外部直接赋值,而是由当前状态对象内部逻辑驱动(例如:OrderStatePaid.handle() 内部调用 context.setState(new OrderStateShipped()))。它像人的年龄——不会被外界强行改成“30岁”,而是自然从29岁跨入30岁。
- 变量值由具体状态类协作更新,常通过 state.handle(context) 反向修改 context 的 state 引用
- 状态变量承载语义依赖:前一状态决定能否进入后一状态(如“已取消”订单不能变回“待支付”)
- 状态对象通常与特定 Context 实例绑定,难以跨实例复用(状态难复用)
变量是否参与行为决策链
策略变量只影响“怎么做”,不改变“能做什么”;状态变量既影响“怎么做”,也限制“能做什么”。
- 策略模式中,所有策略都响应同一方法(如 pay()),只是实现不同——变量切换不改变接口契约
- 状态模式中,同一方法在不同状态下可能抛异常、静默忽略或触发转移(如“已发货”状态下调用 cancel() 可能直接返回 false 或 throw IllegalStateException)
- 状态变量本身是行为合法性的判断依据,而策略变量只是算法参数
变量变更的可见性与时机
策略变更对调用方透明且即时生效;状态变更往往延迟暴露、伴随副作用。
- setStrategy() 调用后,下次 method() 就走新策略——无中间态,无回调
- state.handle() 执行时,可能先完成业务动作(如扣库存),再修改自身状态变量,甚至触发事件通知
- 状态变量的变更常嵌套在业务流程中,不是独立操作,而是流程结果

















