(英国) Traffic Light シミュレーション アプリがあり、TrafficLightクラスには次のように定義された関連する有限状態マシンがあるとします。
* --> RED --> RED_AMBER --> GREEN --> AMBER --> RED --> ...
(repeat until the proverbial cows make an appearance )
建設中のTrafficLightの状態は RED です ある種のタイム トリガーが状態の変化を引き起こします。
アプリには(ポイントから離れたコードを削除する)のようなコードがあるかもしれません...
TrafficLight trafficLightsAtBigJunction = new TrafficLight(); // state = RED
trafficLightsAtBigJunction.setState( TrafficLightState.RED_AMBER );
trafficLightsAtBigJunction.setState( TrafficLightState.GREEN );
trafficLightsAtBigJunction.setState( TrafficLightState.AMBER );
trafficLightsAtBigJunction.setState( TrafficLightState.RED );
trafficLightsAtBigJunction.setState( TrafficLightState.RED_AMBER );
:
:
:
重要なのは、ステート パターンを使用してステート マシンを実装することです。
TrafficLight trafficLightsAtBigJunction = new TrafficLight(); // state = RED
trafficLightsAtBigJunction.setState( TrafficLightState.GREEN ); // Exception!!!!!
これは不正な状態移動であるため、(私たちの設計により) 例外がスローされます。それが私たちが望むものです。すべてが世界とうまくいっています。
しかし、信号機を持続し、それがたまたま state = AMBER である場合、問題があるように見えます。ユーザーが 3 日後に戻ってきて素晴らしい信号機のシミュレーションを見ると、現在の状態から一部の (気にしない) 永続的なストアに復元されます。
ここで状態パターンが提供するカプセル化を壊さずに、信号機インスタンスを AMBER 状態にする方法は?
2 つの選択肢があるようです:- (1) 新しいインスタンスを作成し、関連する状態を実行します (2)慣例により、永続ストアからの読み取り後にのみ使用される、必要な状態に設定する特別なメソッドを提供します. 例えば
trafficLight.setStateAfterReadingFromPersistanceSource( AMBER );
(1)の問題は、状態を実行するときに望ましくない副作用が発生する可能性が非常に高く、さらに状態マシンによってはロジックが非常に複雑になる可能性があることです
(2) の問題は、明らかに慣例に従ってのみ機能するため、誤って使用すると知らずにバグが発生する可能性があることです。さらに重要なことに、最初に望んでいたカプセル化されたすべての素敵なパターンがほとんど壊れてしまいます。
問題は永続化技術にとらわれないことです-ORM、ファイル、シリアライゼーションなどと同じ問題です
ここに解決策があると思いますが、自分では考えられず、グーグルのスキルが十分ではありませんでした。
どんな指針も素晴らしいでしょう。