我使用状态模式来实现一个简单的有限状态机。查看Wikipedia上给出的描述,更具体地说,查看建议的 Java 实现,我想知道为什么实现State
接口的类(即各种状态)不是单例?
在建议的实现中,每当发生转换时都会创建一个新状态。然而,一个对象足以代表每个状态。那么,为什么每次发生转换时都浪费时间创建一个新实例呢?
我使用状态模式来实现一个简单的有限状态机。查看Wikipedia上给出的描述,更具体地说,查看建议的 Java 实现,我想知道为什么实现State
接口的类(即各种状态)不是单例?
在建议的实现中,每当发生转换时都会创建一个新状态。然而,一个对象足以代表每个状态。那么,为什么每次发生转换时都浪费时间创建一个新实例呢?
因为每个状态都可以存储实例变量?
看一下您引用的 Wikipedia 示例:
class StateB implements State {
private int count=0;
public void writeName(StateContext stateContext, String name) {
System.out.println(name.toUpperCase());
if(++count>1) {
stateContext.setState(new StateA());
}
}
}
你能看到它是如何存储输入次数的吗?
现在,在 FSM 中,您可能希望每个状态都是幂等的(后续调用给出相同的反馈),但状态模式更通用。维基百科页面上描述的一种目标用途是:
对象在运行时部分更改其类型的干净方法
由于大多数对象在执行操作时可能使用它们的局部变量,因此您希望“更改类型”版本也使用局部变量。
假设你的对象有一个状态。现在,如果您需要“只需要一个完整的类似的东西”怎么办?
您可能需要一个“有状态”对象(如参考维基百科页面上的一个示例所示),此外,您可能希望在同一个 JVM 中运行多个相同类型的状态机。
如果每个州都是单身人士,这是不可能的。
如果您的状态不需要特定于机器的附加状态数据,那么跨机器重用它们是非常有意义的。这并不意味着它们是单例:单例还意味着您几乎不需要的全局访问。
这是一个简单的状态机,它重用状态,但不会使它们成为单例。
public class SwitchState
{
public SwitchState(bool isOn)
{
mIsOn = isOn;
}
public void InitToggleState(SwitchState state)
{
mToggleState = toggleState;
}
public bool IsOn { get { return mIsOn; } }
public SwitchState Toggle() { return mToggleState; }
private SwitchState mToggleState;
private bool mIsOn;
}
public class LightSwitch
{
public LightSwitch()
{
mState = sOnState;
}
public bool IsOn { get { return mState.IsOn; } }
public void Toggle()
{
mState = mState.Toggle();
}
static LightSwitch()
{
sOnState = new SwitchState(true);
sOffState = new SwitchState(false);
sOnState.InitToggleState(sOffState);
sOffState.InitToggleState(sOnState);
}
private static SwitchState sOnState;
private static SwitchState sOffState;
private SwitchState mState;
}
您可以看到,无论有多少LightSwitch
实例,整个应用程序中都只会有一个开和关状态。同时,没有任何东西LightSwitch
可以访问状态,所以它们不是单例。这是享元模式的经典示例。
应该反过来问这个问题:为什么要State
单身?仅当您需要全局访问并且拥有多个实例时才需要单例。
拥有多个 a 实例当然不是错误State
,而且您也不需要全局访问,因此无需将它们设为单例。