直接の依存関係をメッセージングに置き換える
場合によっては、モジュールで何らかのイベント/変更が発生したことを他のモジュールに通知する必要があるだけで、この情報が後でどうなるかは問題ではありません。
この場合、モジュールは「お互いのことを知っている」必要はまったくありません。つまり、直接リンクが含まれて直接対話する必要はありませんが、メッセージ (メッセージ) またはイベント (イベント) を交換するだけで十分です。
メッセージングを介したモジュール通信は、直接の依存関係よりもはるかに弱いように見えることがあります。実際、メソッドが呼び出されないため、クラスに関する情報はありません。しかし、これは単なる幻想にすぎません。
メソッド名の代わりに、ロジックはメッセージ タイプ、そのパラメータ、および送信データに関連付けられ始めます。このようなモジュールの接続は不鮮明になります。
以前は、メソッドを呼び出す - 接続があるが、メソッドを呼び出さない - 接続がない、という感じでした。ここで、モジュール A がメッセージ内でわずかに異なるデータを送信し始めたと想像してください。同時に、これらのメッセージに依存するすべてのモジュールは正しく動作しなくなります。
以前、新しいユーザーを追加するときに、認可モジュールがメッセージUSER_ADDED を送信し、更新後、登録を試行するときにこのメッセージを送信し、追加で登録が成功したかどうかをパラメータで示すようになったとします。
したがって、メッセージ メカニズムを適切に実装することが非常に重要です。これにはさまざまなテンプレートがあります。
観察者。これは、多くのモジュールが 1 つのモジュール (メインモジュール) の状態に依存する、1 対多の依存関係の場合に使用されます。これはメーリング メカニズムを使用します。これは、メイン モジュールがすべてのサブスクライバに同じメッセージを送信するだけであり、この情報に関心のあるモジュールは「サブスクライバ」インターフェイスを実装してメーリング リストに登録することを意味します。
このアプローチは、ユーザー インターフェイスを備えたシステムで広く使用されており、アプリケーションのコア (モデル) を独立させたまま、関連するインターフェイスに何かが変更され、更新する必要があることを通知できます。
ここでは、メッセージ形式がオペレーティング システム レベルで標準化されており、開発者は下位互換性と適切なドキュメントに注意する必要があります。
メッセージの配布による対話の組織化には、追加の「ボーナス」があります。それは、「公開」(つまり、送信)メッセージに対する「購読者」のオプションの存在です。このように適切に設計されたシステムでは、いつでもモジュールを追加/削除できます。
メッセージングバス
メッセージの交換を整理し、これにMediatorパターンを別の方法で使用できます。
モジュール間に多対多の依存関係がある場合に使用されます。メディエータはモジュール間の通信の仲介者として機能し、通信センターとして機能し、モジュールが相互に明示的に参照する必要がなくなります。
その結果、モジュール間の相互作用 (「すべてとすべて」) は、仲介者とのみのモジュールの相互作用 (「1 とすべて」) に置き換えられます。メディエーターは、複数のモジュール間の相互作用をカプセル化すると言われています。
これがいわゆるスマート仲介者です。開発者がほとんどの場合、特定のメッセージの受信をオン/オフにすることで個々のモジュールの動作に影響を与えるための杖を追加し始めるのはそこです。
典型的な実例は空港の交通管制です。航空機からのすべてのメッセージは、航空機間で直接送信されるのではなく、管制官の管制塔に送られます。そして、管制官はすでにどの飛行機が離陸または着陸できるかを決定し、次に飛行機にメッセージを送信します。
重要!モジュールは、単純なメッセージだけでなく、コマンド オブジェクトも相互に送信できます。このような対話は、コマンドテンプレートによって記述されます。肝心なのは、特定のアクションを実行するリクエストを別のオブジェクトとしてカプセル化することです。
実際、このオブジェクトには 1 つのuse()メソッドが含まれており、このメソッドを使用すると、このアクションを他のモジュールに渡してパラメータとして実行し、通常のオブジェクトで実行できるコマンド オブジェクトを使用したあらゆる操作を実行できます。
デメテルの法則
デメテルの法則は、暗黙的な依存関係の使用を禁止しています。「オブジェクト A がオブジェクト B にアクセスでき、オブジェクト B がオブジェクト C にアクセスできる場合、オブジェクト A はオブジェクト C に直接アクセスできません。」
これは、コード内のすべての依存関係が「明示的」である必要があることを意味します。クラス/モジュールは、その作業で「その依存関係」のみを使用でき、それらを経由して他の依存関係に到達するべきではありません。良い例は 3 層アーキテクチャです。インターフェイス層はロジック層と連携する必要がありますが、データベース層と直接対話するべきではありません。
簡単に言えば、この原則は次のように定式化されます。「友人の友人とはではなく、直接の友人とのみ交流する」。これにより、コードの一貫性が低下し、その設計の可視性と透明性が向上します。
デメテルの法則は、すでに述べた「最小限の知識の原則」を実装しています。これは疎結合の基礎であり、オブジェクト/モジュールが他のオブジェクト/モジュールの構造とプロパティについての詳細をできるだけ少なく知っている必要があるという事実で構成されています。独自のコンポーネントを含む一般的なもの。
人生からの例え:犬を走らせたいなら、その足に命令するのは愚かで、犬に命令した方が良い、そうすれば犬は自分で自分の足を扱うでしょう。
継承ではなく合成
これは非常に大きく興味深いトピックであり、少なくとも別の講義が必要です。このトピックについては、コンセンサスが得られるまで、インターネット上で多くのコピーが作成されました。継承は最小限に、構成は最大限に使用します。
重要なのは、継承は実際にはクラス間の最も強力な接続を提供するため、継承は避けるべきであるということです。このトピックについては、Herb Sutter の記事「継承より合成を優先する」で詳しく説明されています。
デザイン パターンを学習し始めると、オブジェクトやその内部構造の作成を制御する大量のパターンに出会うことになります。ちなみに、この文脈では、ゲームから来たDelegate / DelegateパターンとComponentパターンに注意を払うようにアドバイスできます。
パターンについては後ほど詳しく説明します。
GO TO FULL VERSION