状态模式实战:从条件地狱到优雅状态管理的蜕变——以手机通知模式为例

作者:微信公众号:【架构师老卢】
5-1 8:55
5

🔄 状态模式核心理念:用对象状态替代条件地狱 传统条件分支的困境:

if (state == NORMAL) {
  // 大声响铃
} else if (state == VIBRATE) {
  // 震动模式
} else if (state == SILENT) {
  // 静音模式
}

当状态超过3种时,代码将陷入: ✅ 条件分支爆炸
✅ 逻辑分散维护难
✅ 违反开闭原则

状态模式的革命性解决方案:
🔧 将每个状态封装为独立对象
🔧 通过多态实现行为切换
🔧 上下文对象无需知晓具体实现


📱 手机通知模式实战(Dart实现) 状态接口定义

abstract class PhoneState {
  void onReceiveCall(Phone context);
}

具体状态实现 正常模式(响铃):

class NormalState implements PhoneState {
  @override
  void onReceiveCall(Phone context) {
    print("来电响铃:叮咚!📞 (正常模式)");
  }
}

震动模式(带智能切换逻辑):

class VibrateState implements PhoneState {
  int _vibrateCount = 0;

  @override
  void onReceiveCall(Phone context) {
    _vibrateCount++;
    print("震动模式:滴滴滴... ($(_vibrateCount)次未接) 🔇");
    
    if (_vibrateCount >= 3) {
      context.setState(SilentState()); // 自动切换状态
    }
  }
}

静音模式(完全无声):

class SilentState implements PhoneState {
  @override
  void onReceiveCall(Phone context) {
    print("静音模式:🔕 无提示,通话记录中");
  }
}

上下文对象(手机)

class Phone {
  PhoneState _currentState = NormalState();

  void setState(PhoneState newState) => _currentState = newState;
  
  void receiveCall() => _currentState.onReceiveCall(this);
}

🔄 状态模式核心优势对比 | 特性 | 传统条件分支 | 状态模式 | |---------------------|------------------------------|----------------------------| | 代码可维护性 | 修改需全局调整 | 新增状态只需添加类 | | 状态转换逻辑 | 分散在业务代码中 | 封装在状态对象内部 | | 扩展性 | 添加新状态需修改所有条件分支 | 只需新增状态类 | | 职责单一 | 上下文承担过多逻辑 | 每个状态类专注单一行为 |


⚡ 实际运行效果演示

void main() {
  var phone = Phone();
  
  // 初始状态:正常模式
  phone.receiveCall();  // 输出:叮咚!📞 (正常模式)
  
  // 切换至震动模式
  phone.setState(VibrateState());
  phone.receiveCall();  // 输出:滴滴滴... (1次未接) 🔇
  phone.receiveCall();  // 输出:滴滴滴... (2次未接) 🔇
  phone.receiveCall();  // 输出:自动切换至静音模式
  
  // 静音模式测试
  phone.receiveCall();  // 输出:🔕 无提示,通话记录中
}

🧩 模式适用场景决策树

是否遇到以下问题?
├── 是 → 状态模式
│   ├── 存在多个互斥行为分支
│   ├── 状态转换逻辑复杂
│   └── 预期未来会增加新状态
└── 否 → 保持现状
    ├── 仅有2-3种简单状态
    └── 状态转换逻辑稳定

🔧 进阶实践建议 动态状态配置:

// 通过工厂模式创建状态
public class StateFactory {
    public IState CreateState(string config) {
        return config switch {
            "Normal" => new NormalState(),
            "Vibrate" => new VibrateState(),
            _ => throw new ArgumentOutOfRangeException()
        };
    }
}

状态持久化:

// 将当前状态序列化存储
public class PhoneStateManager {
    public void SaveState(PhoneState state) {
        localStorage.Set("currentState", state.GetType().Name);
    }
}

技术思考:
状态模式本质上是通过对象组合替代条件控制流,将原本隐含在代码中的状态机显式化为对象协作。当你的业务逻辑开始出现"如果...否则..."的嵌套地狱时,这正是系统在向你发出重构信号——是时候让状态对象来接管这些复杂的条件判断了。

相关留言评论
昵称:
邮箱:
阅读排行