ステートチャート パターンは特に switch ステートメントを削除するために使用されることを意図しているため、これは恐ろしい悪用のように聞こえます。さらに、状態は非同期イベントでのみ変更する必要があります。イベントを処理していて、複数の状態 (または for ループなど) を変更する場合、これもパターンの恐ろしい乱用です。
これらの 2 つの点から始めます。それらを修正するだけで、同時実行性の問題の多くが解決されるからです。決定する必要があるのは次のとおりです。
- システムに対する外部の非同期イベントは何ですか? これらは、イベント処理中に発生するものではなく、状態遷移を決定する必要がある唯一のものです。イベントによって、0 または 1 の状態遷移が発生する場合があります。これらの状態遷移のリストを取得したら、システムの実際の状態を再構築できます。UML 状態図を知っている場合は、自分自身のためだけでなく (非常に役立ちますが)、将来 UML 状態図に戻る必要があるすべての人のためにも、チャート作成プログラムで図をスケッチするのに最適な時期です。事業。あなたが学んだように、これは起こります。
- 本当の状態とは何かがわかったので、コード内にあってはならない状態をリストします。これは通常、何かが「機能的に分解」できることを示します。これらのそれぞれの状態オブジェクトの代わりに、おそらく必要なのは個別の関数だけです。これにより、状態オブジェクトのオーバーヘッドが大幅に削減され、コードが大幅にクリーンアップされます。
- 今度は、あなたが言及した恐ろしい switch ステートメントに取り組むときです。それらが本当に状態に基づいている場合は、まったく必要ありません。代わりに、ステート マシンを直接呼び出すことができるはずです。
何かのようなもの:
myStateMachine->myEvent();
スイッチなしで動作するはずです。ただし、これは、非同期イベント間で機能しない一部のオブジェクトにも当てはまる場合があることに注意してください。これは、継承を使用して同じ効果を得ることができる場所の指標でもあります。あなたが持っている場合:
switch (someTypeIdentifier)
{
case type1:
doSomething();
break;
case type2:
doSomethingElse();
break;
}
通常、正しい OOP メソッドは、必要なことを行う仮想メソッド doSomething() を使用して、抽象ベース TypeBase から派生した 2 つの実際の型 Type1、Type2 を作成することです。これが便利な理由は、(Open/Closed Principle の意味で) 処理を "閉じる" ことができ、必要に応じて新しい派生型を追加することで機能を拡張できることを意味するためです (拡張のために開いたままにします)。これにより、開発者は非常に見苦しく複雑になる可能性があるこれらの switch ステートメントから手を差し伸べることができるため、バグが大幅に節約され、代わりに個別の動作が個別のクラスにカプセル化されます。
4 - ここで、スレッドの問題を修正してください。複数のスレッドから使用されるすべてのオブジェクトを識別します。リストを作る。さて、これらはどのように使われますか?それらのいくつかは常に一緒に使用されますか? グループの作成を開始します。ここでの目標は、これらのオブジェクトに最適なカプセル化のレベルを見つけ、オブジェクトを独自の同期を制御する個々のクラスに分離し、オブジェクトの実際の「トランザクション」の原子レベルを把握し、クラスのメソッドを作成することです。適切なミューテックス、条件変数などで舞台裏でラップされた、意味のあるトランザクションを公開します。
あなたは、「それは大変な作業のように聞こえます。なぜ、自分ですべてを書くのではなく、それをすべて行うのですか?」と言っているかもしれません。良い質問!:) 理由は実に単純です。すべてを自分で行う場合は、とにかくこれらの手順を実行する必要があります。状態、動的ポリモーフィズムを特定し、マルチスレッド トランザクションのハンドルを取得する必要があります。しかし、既存のコードから始めると、文書化されていない暗黙のビジネス ルールがすべて含まれており、あらゆる種類の予期しないバグが発生する可能性があります。すべてを持ち込む必要はありません - バグであると思われる場合は、過去にシステムを操作したことがある人 (利用可能な場合)、QA、またはバグを特定できる人とロジックについて話し合い、それが本当にあるかどうかを確認してください。引き継ぐべきです。
最終的に、これはソフトウェア エンジニアリングの一部である手動プロセスです。状態図を作成してコードに公開するのに役立つ CASE ツール、関数とクラスの間でコードを移動するのに役立つ多くの IDE に見られるようなリファクタリング ツール、およびスレッド化の必要性を特定するのに役立つ同様のツールがあります。 . ただし、これらのことを 1 つのプロジェクトに取り上げるべきではありません。これらはソフトウェア エンジニアの一部であるため、キャリアを通じて習得し、何年にもわたる仕事を通じてより深く学ぶ必要があります。彼らはあなたのためにそれをしません。なぜ、どのように行うのかを知る必要があります。