我在我的应用程序中使用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()
:因为它是函数式编程范例。当我以依赖className的方式构建我的架构时,第一个迹象表明出现了问题。对我来说,将instanceof
更改为enum
并不意味着改变架构,而只是改变一个坏事。
如果将每个IState实现作为枚举:每个IState实现都是Hibernate实体。
答案 0 :(得分:2)
Java在Java中创建单例的方法是enum
。这提供了线程安全的初始化以及JVM保证的单例状态。创建class
的第二个实例的方法有很多,而不是enum
。
使用enum
的额外好处是,您可以在逻辑中enum
开启案例:
public enum State {
STATE_A {
@Override
public void doStateDependentLogic(final State newState) {
switch (newState) {
case STATE_B:
//do stuff
//case SOME_OTHER_STATE
}
}
},
STATE_B {
@Override
public void doStateDependentLogic(final State newState) {
}
};
public abstract void doStateDependentLogic(State newState);
}
我不知道你在哪里认为enum
是函数式编程范例。不是这种情况。 Java中的enum
旨在完全按照您的意愿执行。
答案 1 :(得分:1)
你的问题不是状态模式。问题出在状态模式完成之后,就是将方法调用路由到表示状态的某个实现。
子类的instanceof
问题是一个独立的问题。这里的解决方案是避免在其他代码中使用instanceof
,最好通过方法在状态和下一个状态之间进行交互。超过switch
类型的enum
已经看起来更好但是并没有好多,因为您仍然依赖于另一个对象的具体类型。可以认为是好的,因为所有这些都是在同一个类中定义的,因此依赖性只取决于你自己。
在最好的情况下你最终应该看起来像
@Override
public void doStateDependentLogic(IState newState) {
if (newState.isBeautiful()) {
System.out.println(newState.getYourPartOfTheInterAction(this));
} else {
somethingElse();
}
}
即。方法调用抽象而不关心实现细节。