if webの問題に取り組む場合、特定のルールを個別にコーディングするルールエンジンを作成できます。これのさらなる改良は、ルールを作成するためのドメイン固有言語(DSL)を作成することですが、DSLだけでは、あるコードベース(メイン)から別のコードベース(DSL)に問題を置き換えます。構造がなければ、DSLはネイティブ言語(Java、C#など)を上回ることはないので、改善された構造的アプローチを見つけた後、DSLに戻ります。
基本的な問題は、モデル化の問題があることです。このような組み合わせの状況に遭遇するときはいつでも、状況を説明するモデルの抽象化が粗すぎるという明確な兆候です。ほとんどの場合、単一のエンティティ内の異なるモデルに属する要素を組み合わせます。
モデルを分解し続けると、最終的にこの組み合わせ効果が完全に解消されます。ただし、この方法をとる場合、設計で迷子になりやすくなり、さらに大きな混乱が生じます。ここでの完璧主義は必ずしもあなたの友人ではありません。
有限状態マシンとルールエンジンは、この問題をどのように分解して管理しやすくするかの例にすぎません。ここでの主なアイデアは、このような組み合わせの問題を取り除く良い方法は、多くの場合、デザインを作成し、システムが十分に機能するまでネストされた抽象化レベルで繰り返し吐き出すことです。フラクタルを使用して複雑なパターンを作成する方法に似ています。システムを顕微鏡で見る場合でも、高い鳥瞰図で見る場合でも、ルールは同じです。
これをドメインに適用する例。
牛が地形をどのように動いているかをモデル化しようとしています。あなたの質問には詳細が欠けていますが、大量のifには決定フラグメントが含まれif cow.isStanding then cow.canRun = true
ていると思いますが、たとえば地形の詳細を追加すると行き詰まってしまいます。したがって、実行するすべてのアクションについて、考えられるすべての側面をチェックし、次の可能なアクションに対してこれらの検証を繰り返す必要があります。
まず、繰り返し可能な設計が必要です。この場合、シミュレーションの変化する状態をモデル化するFSMになります。したがって、最初に行うことは、参照FSMを実装し、状態インターフェイス、遷移インターフェイス、およびおそらく遷移コンテキストを定義することです他の2人が利用できる共有情報を含めることができます。基本的なFSM実装は、コンテキストに関係なく、ある遷移から別の遷移に切り替えます。これがルールエンジンの出番です。ルールエンジンは、遷移を行う場合に満たす必要がある条件を明確にカプセル化します。ここでのルールエンジンは、それぞれがブール値を返す評価関数を持つルールのリストと同じくらい簡単です。遷移を行う必要があるかどうかを確認するために、ルールのリストを繰り返し、それらのいずれかが偽と評価された場合、遷移は行われません。遷移自体には、FSM(およびその他の可能なタスク)の現在の状態を変更するための動作コードが含まれます。
ここで、シミュレーションをGODレベルで単一の大きなFSMとして実装し始めると、可能性のある状態、遷移などが多数発生します。if-elseの混乱は固定されているように見えますが、実際にはただ広がっています:各IF現在、コンテキストの特定の情報(この時点ではほとんどすべてを含む)に対してテストを実行するルールがあり、各IF本体は遷移コードのどこかにあります。
フラクタルの内訳を入力します。最初のステップは、状態が牛自身の内部状態(立っている、走っている、歩く、放牧など)である各牛のFSMを作成することです。グラフが完全ではない可能性があります。たとえば、放牧は立った状態からのみアクセスでき、他の遷移はモデルに単に存在しないため拒否されます。ここでは、牛と地形という2つの異なるモデルのデータを効果的に分離します。それぞれ独自のプロパティが設定されています。この内訳により、エンジン設計全体を簡素化できます。すべてを決定する単一のルールエンジンを使用する代わりに、非常に具体的な詳細を決定する複数の単純なルールエンジン(遷移ごとに1つ)を使用します。
私はFSMに同じコードを再利用しているため、これは基本的にFSMの構成です。 DSLについて以前に言及したときのことを覚えていますか?これは、書くべきルールとトランジションがたくさんある場合、DSLが多くのことを行える場所です。
さらに深く
現在、GODは牛の内部状態の管理に関する複雑さをすべて処理する必要がなくなりましたが、さらに推進することができます。たとえば、地形の管理には依然として多くの複雑さが伴います。これは、内訳が十分である場所を決定する場所です。たとえば、あなたのGODで地形のダイナミクス(長い草、泥、乾いた泥、短い草など)を管理することになった場合、同じパターンを繰り返すことができます。すべての地形状態(長い草、短い草、泥、乾燥など)を新しい地形FSMに抽出することで、そのようなロジックを地形自体に埋め込むことを妨げるものはありません。たとえば、泥だらけの状態にするには、ルールエンジンがコンテキストをチェックして液体を見つける必要があります。そうでない場合は不可能です。今、神はさらにシンプルになりました。
FSMを自律的にして、それぞれにスレッドを与えることにより、FSMのシステムを完成させることができます。この最後の手順は必要ありませんが、意思決定の委任方法を調整することで、システムの相互作用を動的に変更できます(特殊なFSMを起動するか、単に所定の状態を返すだけです)。
遷移が「他の可能なタスク」を行う可能性があることを説明したことを覚えていますか?異なるモデル(FSM)が互いに通信する可能性を追加することで、それを探ってみましょう。イベントのセットを定義し、各FSMがこれらのイベントにリスナーを登録できるようにすることができます。したがって、たとえば牛が地形へクスに進入した場合、そのへクスは遷移の変化に対してリスナーを登録できます。ここでは、各FSMがそれがハーバーする特定のドメインの知識なしで非常に高いレベルで実装されるため、少し注意が必要です。しかし、牛にイベントのリストを公開させることでこれを達成でき、セルが反応できるイベントを見つけた場合にセルを登録できます。ここでのイベントファミリの優れた階層は、優れた投資です。
草の栄養レベルと成長サイクルをモデリングすることで、さらに深く推し進めることができます。地形パッチの独自のモデルに埋め込まれた草のFSMです。
アイデアを十分に推し進めれば、すべての側面がほとんど自己管理されているため、神はほとんど何もすることができず、より信心深い事柄に時間を割くことができます。
要約
上記のように、ここでのFSMは解決策ではなく、そのような問題の解決策はコードごとにではなく、問題のモデル化方法にあることを示すための手段にすぎません。私のFSMの提案よりも可能性が高く、おそらくはるかに優れた他の解決策が存在する可能性があります。ただし、「フラクタル」アプローチは、この困難を管理するための優れた方法です。正しく実行すれば、重要な場合はより深いレベルを動的に割り当て、重要でない場合はより単純なモデルを提供できます。変更をキューに入れて、リソースが使用可能になったときに適用できます。アクションシーケンスでは、牛から牧草への栄養移動を計算することはそれほど重要ではないかもしれません。ただし、これらの遷移を記録し、後で変更を適用したり、ルールエンジンを単に置き換えたり、FSM実装を直接フィールドにない要素の単純な単純なバージョンに置き換えたりするだけで、経験に基づいた推測で近似することができます関心(フィールドの反対側の牛)により、より詳細な相互作用が焦点を獲得し、リソースをより多く共有できるようにします。システム全体を再確認することなく、これらすべてを実行できます。各パーツは十分に分離されているため、モデルの深さを制限または拡張するドロップイン置換を作成するのが簡単になります。標準設計を使用することで、その上に構築し、DSLなどのアドホックツールへの投資を最大限に活用して、イベントのルールや標準語彙を定義し、再び非常に高いレベルから開始し、必要に応じて改良を加えることができます。各パーツは十分に分離されているため、モデルの深さを制限または拡張するドロップイン置換を作成するのが簡単になります。標準設計を使用することで、その上に構築し、DSLなどのアドホックツールへの投資を最大限に活用して、イベントのルールや標準語彙を定義し、再び非常に高いレベルから開始し、必要に応じて改良を加えることができます。各パーツは十分に分離されているため、モデルの深さを制限または拡張するドロップイン置換を作成するのが簡単になります。標準設計を使用することで、その上に構築し、DSLなどのアドホックツールへの投資を最大限に活用して、イベントのルールや標準語彙を定義し、再び非常に高いレベルから開始し、必要に応じて改良を加えることができます。
私はコード例を提供しますが、これで今できることはこれだけです。