发布于2026-07-04 阅读(0)
扫一扫,手机访问
先抛出一个核心观点:将状态转换逻辑封装到每个状态类内部,新增状态时只需添加新类,无需修改现有状态类。这才是真正遵循开闭原则的状态模式实践。
传统状态模式实现中,状态间的转移逻辑往往散落在各个 evKey 方法里,新增一个状态就要反复修改多个已有状态类——这直接触碰了开闭原则(Open-Closed Principle, OCP)的红线:“对扩展开放,对修改关闭”。要想真正解耦、提升可维护性,关键在于把“何时切换”和“切换到哪个状态”这两项职责从上下文(SecretKeeper)中剥离出来,交给具体状态类自己决策。
那么,具体怎么改?
SecretKeeper 不再直接调用 setState(new XxxState()),而是委托当前状态完成“输入处理 → 验证 → 决策跳转”全流程;State 实现类负责:
setCode + doStuff);getSwitchedState());SecretKeeper.evKey() 变为统一协调者:仅执行标准流程,不感知具体状态逻辑。public class SecretKeeper {
private final int secretCode;
private final String secret1, secret2;
private State state;
public SecretKeeper(int secretCode, String secret1, String secret2) {
this.secretCode = secretCode;
this.secret1 = secret1;
this.secret2 = secret2;
this.state = new LockedState(); // 初始状态
}
void printSecret1() { System.out.println(secret1); }
void printSecret2() { System.out.println(secret2); }
boolean checkCode(int code) { return code == secretCode; }
void evKey(int digit) {
state.setCode(digit); // 输入处理
state.doStuff(); // 执行当前状态行为(如打印、重置等)
if (checkCode(state.getCode())) {
state = state.getSwitchedState(); // ✅ 状态切换由当前状态决定
}
}
}
对应接口与状态实现:
public interface State {
void setCode(int digit);
int getCode();
State getSwitchedState(); // 核心:切换目标由状态自己返回
void doStuff();
}
public class LockedState implements State {
private int code = 0;
@Override
public void setCode(int digit) {
if (digit == 0) code = 0;
else code = code * 10 + digit;
}
@Override
public int getCode() { return code; }
@Override
public State getSwitchedState() {
return new SemiLockedState(); // ✅ 新增 SemiLocked?只改此处!
}
@Override
public void doStuff() {
// 当前无副作用,仅累积输入
}
}
public class SemiLockedState implements State {
@Override
public void setCode(int digit) { /* ... */ }
@Override
public int getCode() { return 0; }
@Override
public State getSwitchedState() {
return new UnlockedState(); // 可灵活配置后续状态
}
@Override
public void doStuff() {
// 如:播放提示音、点亮指示灯等
}
}
public class UnlockedState implements State {
private int lastDigit;
@Override
public void setCode(int digit) { this.lastDigit = digit; }
@Override
public int getCode() { return lastDigit; }
@Override
public State getSwitchedState() {
return new LockedState(); // 或返回其他状态(如 TimeoutState)
}
@Override
public void doStuff() {
switch (lastDigit) {
case 1 -> printSecret1();
case 2 -> printSecret2();
case 0 -> {} // 保持 unlocked?或触发锁定?由业务定
default -> {}
}
}
// 注意:printSecret1/2 需通过 SecretKeeper 实例访问 —— 建议注入或回调
// 实际中可将 SecretKeeper 作为参数传入 doStuff(),避免静态调用
}
SecretKeeper.printSecret1() 是静态调用,破坏了封装性。推荐改为在 doStuff(StateContext context) 中传入上下文对象,或使用策略回调。getSwitchedState() 返回新实例,并确保 state 字段 final + volatile(配合同步)。StateFactory.getState(String name))或枚举驱动,进一步解耦创建逻辑。setCode、getCode 和 getSwitchedState 行为,无需启动整个系统。遵循开闭原则的状态模式,本质是将变化点封装为可插拔的组件。当需求要求新增 SemiLocked 状态时,你只需:
SemiLockedState 类并实现 State 接口;LockedState.getSwitchedState() 中返回它;UnlockedState 是否允许回到 SemiLocked)。全程无需修改任何已有状态类的 evKey 或分支逻辑,也无需触碰 SecretKeeper 的核心流程——这才是真正可演进、易维护的面向对象设计。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8