質問

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

それは悪いことです。

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

それでいい。

しかし、クラスの凝集度が低くなるようです。もはやそれが正確に何をするのかを単に担当するだけでなく、ある意味で、関連オブジェクトのインターフェースの一部を複製することによりコードの凝集性を低くするデリゲートも持っています。

それは悪いことです。

実際に結束力を低下させるのでしょうか?それは2つの悪の小さい方ですか?

これは開発の灰色の領域の1つであり、線がどこにあるのか、線を引く場所とその判断に使用できる基準を決定するための原則的な方法について議論することができますか?

役に立ちましたか?

解決

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

"まとまりのアイデアは、構造化されたデザインからも生まれます。簡単に言えば、凝集 単一モジュールの要素間の接続性の程度を測定します(そして オブジェクト指向設計の場合、単一のクラスまたはオブジェクト)。最も望ましくない形 凝集は偶然の凝集であり、完全に無関係な抽象化は 同じクラスまたはモジュールにスローされます。たとえば、次を含むクラスを考えます 犬と宇宙船の抽象化。その行動はまったく無関係です。の 凝集の最も望ましい形態は、機能的凝集です。 クラスまたはモジュールはすべて一緒に機能して、いくつかの適切な動作を提供します。 したがって、クラスDogは、そのセマンティクスが動作を包含している場合、機能的に凝集しています。 犬、犬全体、そして犬以外は何もありません。"

上記の顧客とのSubsitute Dog、それは少し明確かもしれません。したがって、目標は実際には機能的な結合を目指して、可能な限り偶然の結合から離れることです。抽象化に応じて、これは単純な場合もあれば、リファクタリングが必要になる場合もあります。

注意結束は" module"にも当てはまります。単一のクラス、つまり一緒に動作するクラスのグループよりも。したがって、この場合、CustomerクラスとOrderクラスは、この強い関係を持ち、顧客が注文を作成し、注文が顧客に属しているため、まともな結束力があります。

マーティン・ファウラーは、「デメテルの提案」と呼ぶ方がより快適だと言います。 (モックはスタブではありませんをご覧ください):

&quot; Mockistテスターは、「列車の残骸」を回避することについてもっと話します-getThis()。getThat()。getTheOther()のスタイルのメソッドチェーン。メソッドチェーンの回避は、デメテルの法則に従うことでも知られています。メソッドチェーンは臭いですが、転送方法で肥大化した中間男性オブジェクトの反対の問題も臭いです。 (<デメテルの法則> デメテルの提案と呼ばれれば、デメテルの法則の方がずっと快適だといつも感じていました。)&quot;

それは私がどこから来たのかをうまくまとめています:「法律」への厳格な遵守よりも低いレベルの凝集力を持つことは完全に受け入れられ、しばしば必要です。必要かもしれません。偶然の結合を避け、機能的な結合を目指しますが、設計の抽象化により自然に適合するために必要な場所を調整することにこだわらないでください。

他のヒント

デメテルの法則に違反している場合、

int price = customer.getOrder().getPrice();

解決策は、getOrderPrice()を作成してコードを変換することではありません

int price = customer.getOrderPrice();

しかし、これは tellしないでください。尋ねる

結束の意味を誤解していると思います。他のいくつかのクラスの観点から実装されたクラスは、明確な概念を表し、明確な目的を持っている限り、必ずしも凝集度が低いとは限りません。たとえば、クラス Date (生年月日)、 Address 、および< code> Education (その人が通った学校のリスト)。 Person であるという事実を暴露しないように、生年月日、最後に通った学校、または彼が住んでいる州を取得するために、 Person でラッパーを提供できます。それらの他のクラスの観点から実装されています。これによりカップリングは減少しますが、 Person の凝集性は低下します。

これは灰色の領域です。 これらのプリンシパルは、あなたがあなたのために働いているとわかった場合(つまり、彼らがあなたの邪魔をしている、および/またはあなたがそれを見つけてコードを複雑にしている場合)、あなたの仕事を助けるためのものです順応が厳しすぎるため、やり直す必要があります。

あなたのために機能させてください、それのために機能しないでください。

これが実際に凝集力を低下させるかどうかはわかりません。

Aggregation / compositionは、パブリックメソッドを介して公開するコントラクトを満たすために、他のクラスを利用するクラスに関するものです。 クラスは、その関連オブジェクトのインターフェースを複製する必要はありません。実際に、これらの集約されたクラスに関する知識をメソッド呼び出し元から隠しています。

クラスの依存関係が複数レベルの場合にDemeterの法則に従うには、各レベルで集約/構成と適切なカプセル化を適用するだけです。

つまり、各クラスには他のクラスに1つ以上の依存関係がありますが、これらは参照されるクラスにのみ依存し、プロパティ/メソッドから返されるオブジェクトには依存しません。

カップリングと凝集の間にトレードオフがあるように思われる状況では、おそらく他の誰かがすでにこのロジックを書いていて、バグを探していた場合、私はおそらく自分自身に尋ねます?&quot;を使用して、そのようにコードを記述します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top