構文解析ツリー、抽象構文ツリー、および制御フローグラフがあり、それぞれが前のものから論理的に派生しているとします。原則として、解析ツリーがあれば各グラフを作成するのは簡単ですが、解析ツリーが変更されたときにグラフを更新する複雑さをどのように管理できますか?私たちはツリーがどのように変更されたかを正確に知っていますが、管理が難しくならない方法で変更を他のツリーにどのように伝播できますか?
当然ながら、依存グラフは最初のグラフが変更されるたびに最初から再構築するだけで更新できますが、依存グラフの変更の詳細を知る方法はありません。
現在、この問題を解決する方法は4つありますが、それぞれに問題があります。
- 従属ツリーのノードはそれぞれ、元のツリーの関連ノードを監視し、必要に応じて自身と元のツリーノードのオブザーバーリストを更新します。これの概念的な複雑さは困難になる可能性があります。
- 元のツリーの各ノードには、それに依存する従属ツリーノードのリストがあり、ノードが変更されると、従属ノードにフラグを設定して、従属ノードの親を含め、ダーティとしてマークします。ルートに。変更のたびに、依存グラフを最初から作成するアルゴリズムとよく似たアルゴリズムを実行しますが、クリーンノードをスキップして各ダーティノードを再構築し、再構築されたノードが実際にダーティノードと異なるかどうかを追跡します。これも注意が必要です。
- 元のグラフと従属グラフの間の論理的な接続を、おそらく宣言型言語を使用して設計された制約のリストのようなデータ構造として表すことができます。元のグラフが変更された場合、違反している制約と違反を修正するために依存ツリーをどのように変更する必要があるかを見つけるためにリストをスキャンするだけで、すべてデータとしてエンコードされます。
- 既存の依存グラフがないかのように、依存グラフを最初から再構築し、既存のグラフと新しいグラフを比較して、どのように変化したかを確認できます。違いを検出するために利用できるアルゴリズムがあることを知っているので、これが最も簡単な方法であると確信していますが、それらはすべて非常に計算コストが高く、原則として不要と思われるため、このオプションは意図的に避けています。
この種の問題に対処する正しい方法は何ですか?確かに、このすべてをほぼ簡単にするデザインパターンがなければなりません。この一般的な説明のすべての問題に対して適切な解決策があると便利です。このクラスの問題には名前がありますか?
この問題が引き起こすトラブルについて詳しく説明しましょう。この問題は、プロジェクトの2つの部分がグラフを操作するたびにさまざまな場所で発生します。各グラフは、ソフトウェアの実行中に変化する同じものの異なる表現です。これはインターフェースのアダプターを作成するようなものですが、単一のオブジェクトまたは固定数のオブジェクトをラップする代わりに、任意のサイズのグラフ全体をラップする必要があります。
私がこれを試す度に、私は混乱して維持不可能な混乱に終わります。オブザーバーの制御フローは、複雑になると追跡が困難になる可能性があります。あるグラフを別のグラフに変換するアルゴリズムは、通常、レイアウトが明確で複数のクラスにまたがっていない場合に追跡するには十分な注意が必要です。問題は、元のグラフが変更されているときに、単純で単純なグラフ変換アルゴリズムだけを使用する方法がないように見えることです。
当然のことながら、通常のグラフ変換アルゴリズムを直接使用することはできません。ゼロから開始する以外の方法で変更に対応できないためです。代わりの方法は何ですか?おそらく、アルゴリズムは継続渡しスタイルで記述できます。この場合、アルゴリズムの各ステップは、ビジターのように、元のグラフのノードのタイプごとにメソッドを持つオブジェクトとして表されます。次に、さまざまな単純なビジターを組み合わせてアルゴリズムを組み立てることができます。
別の例:JPanelsとレイアウトマネージャーを使用して、Java Swingの場合と同じようにレイアウトされたGUIがあるとします。複雑なレイアウトマネージャーの代わりにネストされたJPanelsを使用することでそのプロセスを簡略化できるため、レイアウト目的でのみ存在し、それ以外の場合は無意味なノードを含むさまざまなコンテナーのツリーになります。ここで、GUIの生成に使用されたものと同じツリーがアプリケーションの別の部分でも使用されていると想定しますが、ツリーをグラフィカルにレイアウトする代わりに、抽象表現ツリーをフォルダーのシステムとして生成するライブラリーを操作します。このライブラリを使用するには、レイアウトノードを持たないバージョンのツリーが必要です。レイアウトノードを親ノードにフラット化する必要があります。
もう1つの見方:可変ツリーを操作するというまさにその概念は、デメテルの法則に違反しています。構文解析ツリーや構文ツリーが通常のように値である場合は、実際には法律違反にはなりませんが、その場合は何も最新の状態に保つ必要がないため問題はありません。それで、この問題はデメテルの法則に違反した直接の結果として存在しますが、ドメインがツリーまたはグラフの操作に関するものであるように思われる場合、一般的にどのようにそれを回避しますか?
複合パターンは、 1つのオブジェクトにグラフを回すとデメテルの法則に従うための素晴らしいツールです。ある種類のツリーを別の種類のツリーに効果的に変換するために複合パターンを使用することは可能ですか?抽象構文木や制御フローグラフのように機能するように、複合解析ツリーを作成できますか?単一責任の原則に違反せずにそれを行う方法はありますか?複合パターンは、クラスが彼らが触れるすべての責任を吸収する傾向がありますが、おそらくそれは戦略パターンと何らかの形で組み合わせることができます。