カップリング、凝集、デメテルの法則 質問する

カップリング、凝集、デメテルの法則 質問する

デメテルの法則は、直接知っているオブジェクトとのみ通信するべきであることを示しています。つまり、他のオブジェクトと通信するためにメソッドチェーンを実行しないでください。これを行うと、中間オブジェクトとの不適切なリンクが確立され、不適切にカップリングあなたのコードを他のコードに。

それは良くないね。

解決策としては、あなたが知っているクラスが、関係のあるオブジェクトに責任を委任する単純なラッパーを本質的に公開することです。

それは良い。

しかし、その結果、クラスの凝集もはや単に実行内容を正確に担当するだけでなく、ある意味では、関連オブジェクトのインターフェースの一部を複製することによってコードの一貫性を低下させるデリゲートも持っています。

それは良くないね。

それは本当に結束力を低下させる結果となるのでしょうか? それは二つの悪のうちのよりましな方なのでしょうか?

これは開発のグレーゾーンの 1 つであり、どこに線を引くべきかを議論できるものなのでしょうか。それとも、どこに線を引くべきか、またその決定を下すためにどのような基準を使用できるかについて、強力で原則的な決定を下す方法があるのでしょうか。

ベストアンサー1

Grady Booch の「オブジェクト指向分析と設計」より:

「凝集性という概念も、構造化設計から生まれたものです。簡単に言えば、凝集性は、単一のモジュール (オブジェクト指向設計の場合は単一のクラスまたはオブジェクト) の要素間の接続性の度合いを測定します。最も望ましくない凝集性は、まったく無関係な抽象概念が同じクラスまたはモジュールに投げ込まれる偶然の凝集性です。たとえば、犬と宇宙船の抽象概念を含むクラスを考えてみましょう。これらの抽象概念の動作はまったく無関係です。最も望ましい凝集性は機能的凝集性です。機能的凝集性では、クラスまたはモジュールの要素がすべて連携して、適切に境界が定められた動作を提供します。したがって、クラス Dog は、そのセマンティクスが犬の動作、犬全体、および犬以外の動作を包含する場合、機能的に凝集性があります。」

上記の Dog を Customer に置き換えると、もう少しわかりやすくなるかもしれません。したがって、目標は実際には機能的な凝集性を目指し、偶然の凝集性から可能な限り離れることです。抽象化によっては、これは簡単な場合もあれば、リファクタリングが必要になる場合もあります。

凝集性は、単一のクラス、つまり連携して動作するクラスのグループだけでなく、「モジュール」にも同様に適用されることに注意してください。したがって、この場合、Customer クラスと Order クラスは、顧客が注文を作成し、注文は顧客に属するという強い関係を持っているため、適切な凝集性を維持しています。

マーティン・ファウラーは、これを「デメテルの提案」と呼ぶ方が安心だと言う(記事参照)。モックはスタブではない):

「モックテストのテスト担当者は、getThis().getThat().getTheOther() のようなメソッドチェーンの「列車事故」を避けることについてよく話します。メソッドチェーンを避けることは、デメテルの法則に従うことでも知られています。メソッドチェーンは臭いですが、転送メソッドで肥大化した中間オブジェクトの反対の問題も臭いです。(私は、デメテルの法則を「デメテルの法則」と呼ぶ方が安心できると感じていました。デメテルの示唆。)"

これは、私が言いたいことをうまくまとめたものです。つまり、「法則」を厳密に遵守するために必要なレベルよりも低い凝集度を持つことは、まったく問題がなく、多くの場合必要です。偶然の凝集度を避け、機能的な凝集度を目指しますが、デザインの抽象化に自然に適合させるために必要な微調整にこだわらないでください。

おすすめ記事