State パターンを使用して、単純な有限状態マシンを実装しました。ウィキペディアで提供されている説明、具体的には推奨される Java 実装を見て、State
インターフェイス (つまり、さまざまな状態) を実装するクラスがシングルトンではないのはなぜだろうか?
推奨される実装では、遷移が発生するたびに新しい状態が作成されます。ただし、各状態を表すには 1 つのオブジェクトで十分です。では、遷移が発生するたびに新しいインスタンスを作成して時間を無駄にするのはなぜでしょうか?
State パターンを使用して、単純な有限状態マシンを実装しました。ウィキペディアで提供されている説明、具体的には推奨される Java 実装を見て、State
インターフェイス (つまり、さまざまな状態) を実装するクラスがシングルトンではないのはなぜだろうか?
推奨される実装では、遷移が発生するたびに新しい状態が作成されます。ただし、各状態を表すには 1 つのオブジェクトで十分です。では、遷移が発生するたびに新しいインスタンスを作成して時間を無駄にするのはなぜでしょうか?
各状態はインスタンス変数を格納できるので?
参照しているウィキペディアの例を見てください。
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では、おそらく各状態をべき等にしたいでしょう(後続の呼び出しは同じフィードバックを与えます)が、状態パターンはより一般的です。ウィキペディアのページで説明されている1つのターゲット用途は次のとおりです。
オブジェクトが実行時にそのタイプを部分的に変更するためのクリーンな方法
ほとんどのオブジェクトはおそらくアクションを実行するときにローカル変数を使用するため、「変更されたタイプ」バージョンでもローカル変数を使用する必要があります。
'stateful-State'オブジェクト(参照ウィキペディアページで1つの例として示されているような)が必要な場合があり、さらに、同じ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;
}
インスタンスの数に関係なく、アプリケーション全体でオンとオフの状態が 1 つしかないことがわかりLightSwitch
ます。同時に、外部LightSwitch
から状態にアクセスできるものは何もないため、シングルトンではありません。これは Flyweight パターンの典型的な例です。
オブジェクトに状態があるとします。では、「そのような全体がもう 1 つだけ」必要な場合はどうでしょうか。
質問は逆に尋ねる必要があります:なぜState
シングルトンとして持っているのですか?シングルトンは、グローバルアクセスが必要な場合にのみ必要であり、複数のインスタンスがあるとエラーになります。
のインスタンスが複数あることは間違いなくエラーState
ではありません。また、グローバルアクセスも必要ないため、シングルトンにする必要はありません。