1

次のようなものがあるとします (残念ながら、元のコードを投稿することは許可されていません)。

public void foo() {
    MyObject obj = getMyObject();

    bar(obj);
}

public void bar(MyObject obj) {
   Type type = new Type(obj.getOtherObject());
}

fooを呼び出しbar、 を渡しobjます。ただし、を使用する代わりにobj、ゲッターを呼び出して必要な情報を取得します。これはデメテルの法則に違反していますか?

以下のように書いた方が良いでしょうか?

public void foo() {
    MyObject obj = getMyObject();

    bar(obj.getOtherObject());
}

public void bar(MyOtherObject otherObj) {
   Type type = new Type(otherObj);
}
4

1 に答える 1

2

実際、デメテルの法則に関するウィキによると:

基本的な概念は、特定のオブジェクトは、他のものの構造やプロパティについて可能な限り想定しないでください...

あなたbarは、与えられたMyObject(非常に強く結合された具体的な型で、再び LoD に対して) と呼ばれるメソッドを持っているとgetOtherObject想定しているため、提案されたソリューションはその仮定をソートし、コードを LoD の遵守に近づけます。さらに進んで、代わりに必要なタイプを提供できますbar

bar(new Type(obj.getOtherObject());

言語によっては、ソリッド型の代わりにインターフェイス/コントラクトを渡すことはできませんか? これにより、強い結合がより緩い結合に変わります。

もちろん、これがすべて特定のオブジェクトの内部にある場合は、「親しい友人」であるため、LoD を壊していない可能性があります。

  • 各ユニットは、他のユニットに関する限られた知識のみを持つ必要があります。現在のユニットに「密接に」関連するユニットのみです。
  • 各ユニットは、その友達とのみ会話する必要があります。見知らぬ人と話さないでください。
  • 直接の友達とのみ話してください。

オブジェクト指向では、この引数に基づいて元のコードが LoD を破っていると思います:

...オブジェクト A はオブジェクト インスタンス B のサービスを要求する (メソッドを呼び出す) ことができますが、オブジェクト A はオブジェクト B を「経由して」別のオブジェクト C にアクセスし、そのサービスを要求することはできません。そうすることは、オブジェクト A が暗黙のうちにオブジェクト B の内部構造についてより多くの知識を必要とすることを意味します。

objを呼び出すために使用しているようですgetOtherObj。提案されたコードは潜在的な解決策です。

于 2011-11-24T10:46:04.043 に答える