【发布时间】:2014-01-18 19:19:55
【问题描述】:
我在我的应用程序中使用state pattern,因为我的state-entities 具有API,其行为会因当前状态而改变。
在我的情况下,依赖于状态的 API 仅由一种方法组成 - changeState。这个方法改变状态,也执行一些状态相关的逻辑。
但是有一种情况让我提出了这个问题:状态依赖逻辑不仅依赖于当前状态,还依赖于 newState(见下面的代码)。所以我必须使用instanceof。
问题: 真正摆脱instanceof的方法是什么?
public interface IStateEntity {
void changeState(IState newState);
}
public interface IState {
void doStateDependentLogic(IState newState);
}
public class StateEntityImpl {
private IState state;
@Override
public void changeState(IState newState) {
state.doStateDependentLogic(newState);
state = newState;
}
}
public class StateImplA { //each state implementation is a singleton
@Override
public void doStateDependentLogic(IState newState) {
// HARDSHIP #1: state dependent logic depends not only on current state, but also it depends on newState. So I have to use `instanceof`
if (newState instanceof StateImplA) {
//do one logic
} else if (newState instanceof StateImplB) {
//do another logic
}
}
}
编辑(为什么不枚举):
如果枚举替换 getClass().getSimpleName(): 因为它是函数式编程范式。当我以依赖类名的方式创建架构时,这是出现问题的第一个迹象。在我看来,将 instanceof 更改为 enum 并不意味着要更改架构,而只是为了更改一个坏的更糟。
如果将每个 IState 实现设为枚举:每个 IState 实现都是 Hibernate 实体。
【问题讨论】:
-
另一种方法是创建一个
enum,枚举所有可能的状态并用它“标记”每个IState实例。如果你采用这种方法,你甚至可以switch覆盖它(例如switch(newState.state) -
如果你的州是单身,那么你的州使用
enum。然后,您可以在逻辑中使用switch。 -
@jedwards 你的意思是每个州都应该持有一个适当的最终枚举值吗?但是我的状态已经是单例了,这意味着
simpleClassName已经完成了这个逻辑。 -
@BoristheSpider jedwards 请提供更多详细信息
-
@jedwards 请参阅我的问题的编辑部分
标签: java design-patterns architecture state-pattern