有限ステート マシンは、一般に OOP の悪い設計と見なされますか?
私はそれをよく聞きます。そして、それを利用する非常に古い文書化されていない C++ の部分に取り組まなければならなかった後、私は同意する傾向があります。デバッグするのは苦痛でした。
可読性/保守性の問題はどうですか?
有限ステート マシンは、一般に OOP の悪い設計と見なされますか?
私はそれをよく聞きます。そして、それを利用する非常に古い文書化されていない C++ の部分に取り組まなければならなかった後、私は同意する傾向があります。デバッグするのは苦痛でした。
可読性/保守性の問題はどうですか?
FSMは決して悪いと見なされるべきではありません。それらはあまりにも便利ですが、それらに慣れていない人々はしばしばそれらを負担と見なします。
OOPを使用して実装する方法は多数あります。他のものより醜いものもあります。低レベルの人は、switchステートメント、ジャンプテーブル、さらには「goto」を使用します。
よりクリーンな方法をお探しの場合は、C++でUML状態図を実装するためだけに構築されたBoostの状態チャートライブラリをお勧めします。それは物事をより読みやすくするために、最新のテンプレート技術を利用しています。また、非常に優れたパフォーマンスを発揮します。
有限ステート マシンは、特定の目的を達成するためのツールです。他のツールと同様に、それらも悪用される可能性があります。
彼らは最も優雅なツールではありませんが、彼らが得意とする仕事は、他の手段ではほぼ不可能です (通常、他のアプローチは、機械よりも何千倍もひどい混乱になる運命にあります)。
ジョブは、従来の待機状態が禁止されている状態で動作しています。
タッチスクリーンを読む必要があります。位置を読み取るには、SPI 経由で約 15 のコマンドを交換する必要があります。毎秒100回の読み取りが必要です。続行する前に、それぞれのビジー フラグが消えるまで、各コマンドの後に約 1 マイクロ秒待つ必要があります。コントラストの設定、モードの変更、バックライトのオン/オフ、温度の読み取りなど、同じインターフェイスで達成できる必要がある他の操作も多数あります。while(BUSY_BIT);
待機ごとに実行すると、一瞬のうちにすべての CPU を使い果たします。sched_yield()
またはを行った場合usleep(1)
、必要な読み取り回数を達成することはできません。唯一の方法は、有限ステート マシンです。
しかし、有限状態マシンをうまく機能させる方法もあります。マシンを舞台裏に隠し、開発者が操作できる機能を提供します。
これまでの私の仕事の経験は、3 つの異なる有限状態マシンに基づく 2 つのシステムに支配されていました。
構造的に、または順番に記述した場合、コードは 2 倍シンプルになり、3 倍明確になります。それが機能しないか、ひどいパフォーマンスで機能することを除いて。
彼らが言うことをあなたに言うことができませんでした。
しかし、OOとFSMは、異なる問題のドメインを攻撃します。オブジェクトが相互作用しているドメインでは、オブジェクト指向のアプローチが必要です。世界がある状態または別の状態にあるドメインでは、FSM設計が必要です。
現実的には、これらのデザインをさまざまな抽象化レベルと組み合わせることができます。これにより、どちらか一方だけを使用するよりもクリーンになります。
有限状態マシンは、同じ問題(正規言語のマッチングなどの問題)を解決する他の方法よりもデバッグがはるかに簡単だと思います。FSMの優れている点は、すべてその名のとおりです。15の状態を持つステートマシンがある場合があるため、すべての遷移を示す図を紙に描くことができます。この図を使用して、システムが受け入れる文字列やエラー状態になる方法など、システムの有用なプロパティを把握できます。より複雑なシステムでは、図表化はしばしば困難または不可能です。
「ゴトは悪だ」と言う人々でさえ、ステートマシンを実装する正しい方法だと考えています。(もちろん、ゴトは常に邪悪だと考える人もいます...しかし、みんなを喜ばせることはできません)。
コードが十分に文書化されていれば、OOP アプローチを使用して実装しても問題はないと思います。C/C++ のほとんどは、switch ステートメントを使用して FSM を実装するために使用されます。これは、マシンが大きい場合に可読性を損なうことがあります。
最近、正規言語を解析する必要があり、OOP アプローチを使用して FSM を実装しました。コードの可読性と保守性は良好でした。つまり、大きな switch ステートメントを使用するよりもはるかに優れています。
ヒントとして、最初に、状態を含む FSM と遷移を含む状態を実装しました。ただし、私の場合は、1 つの状態のコレクションと別の遷移のコレクションを含む FSM を表すクラスを作成する方が優れたアプローチであることがわかりました。マシンのクローンを作成し (それは私にとって必要条件でした)、移行機能を小さくすることが容易になりました。
お役に立てば幸いです、カルロス。
ステートマシンは、任意のクラスの動作を表すために使用できます。着信イベントの順序がクラスの動作(組み合わせクラス)に関係ない場合、状態モデルを使用しても特別なメリットはありません。
ただし、クラスの動作が着信イベントの順序に依存する場合(シーケンシャルクラス)、ステートマシンは、動作の分析と実装に最適な選択肢です。
読みやすさ/保守性が懸念される場合は、グラフィック表現を使用してください。さまざまなエンジニアリングドメインに属するクラスの動作の例は、http://www.StateSoft.org- > StateMachineGalleryにグラフィカルで実行可能な形式で示されています。
-ヤヌス