デメテルの法則は方法にのみ適用されますか?
-
10-10-2019 - |
質問
私が見たLODの説明(たとえば、 ウィキペディア, C2 wiki)メソッドを呼び出さないことについて話します。ウィキペディアを引用する:
関数のデメテルの法則では、オブジェクトの方法mができることが必要です メソッドのみを呼び出します 次の種類のオブジェクトのうち、
-oそれ自体
-Mのパラメーター
-m内で作成/インスタンス化されたオブジェクト
-Oの直接コンポーネントオブジェクト
-Mの範囲内でOがアクセスできるグローバル変数
しかし、プロパティ、変数、または列挙にアクセスするのはどうでしょうか?たとえば、これを考えると、
class FirstClass {
public SecondClass GetRelatedClass() {
return new SecondClass();
}
public enum InnerEnum {
Violated,
NotViolated
}
}
class SecondClass {
public int Property {get; set;}
public string _variable = "Danny Demeter";
}
これらのLOD違反はすべて/すべてですか? (今のところ、できる限り直接変数アクセスを無視してください。)
void Violate(FirstClass first) {
SecondClass second = first.GetRelatedClass();
var x = second.Property;
var y = second._variable;
var z = FirstClass.InnerEnum.Violated;
}
私は最初の2つ(「公式」違反かどうかにかかわらず)をしませんが、列挙についてはあまり確信していません。
解決
列挙の質問に答えることはできません。標準的な推奨事項は、クラス内の列挙を定義することではないことを思い出しているようです。
プロパティの場合、プロパティは本当にメソッドのショートカットであると考えることができます(getProperty()
と setProperty(value)
)。その場合、あなたの答えは、プロパティアクセスが違反であるということです。
フィールド(変数)の場合、もう一度、一般的な慣行はそれらを公開することではなく、プロパティを使用することです。実際にフィールドを公開することはカプセル化の違反です。
最終的には、デメテルの法則の意図は、クラス間の実装の知識を制限することです。私にとって、それはあなたの例のすべてが違反であることを意味します。
他のヒント
fwiw ...
違反#1(x)は大まかなサービスの位置パターンのように見えるので、この例は違反ではないと思われます。
違反#2(Y)はクラスのデザインの匂いのように見えますが、一般に違反#1が示しているものを超えて何も示していません。
公共の列挙(z)は、スコープされていますが、ここでLODにカウントされるとは思いません。
あなたの懸念を示すためのより良い現実世界の例はありますか?適切なコンテキストがなければ、単純なコードの例は問題ないか、設計原則に違反する可能性があります。