デメテルの法則によれば、クラスはそのメンバーの1人を返すことを許可されていますか?
はい、最も確かです。
主なポイントを見てみましょう:
- 各ユニットは、他のユニットに関する限られた知識のみを持つ必要があります。現在のユニットに「密接に」関連するユニットのみです。
- 各ユニットは、その友人とのみ会話する必要があります。見知らぬ人と話をしないでください。
- 身近な友達とだけ話してください。
これら3つすべてから、1つの質問をすることができます 。友達は誰ですか?
何を返すかを決定する際、デメテルの法則または最少知識の原則(LoD)は、違反を主張するコーダーを防御することを指示するものではありません。コーダーに強制的に違反させないよう指示します。
これらを混乱させることがまさにセッターが常にvoidを返さなければならないと考える理由です。いいえ。システムの状態を変更しないクエリ(ゲッター)を作成する方法を許可する必要があります。これが基本的なコマンドクエリの分離です。
これは、あなたが望むものを一緒に連鎖するコードベースを自由に掘り下げることができるということですか?いいえ。一緒にチェーンすることを意図したものだけを一緒にチェーンします。そうしないと、チェーンが変更され、突然あなたのものが壊れる可能性があります。これが友達の意味です。
長いチェーンを設計できます。流interfacesなインターフェース、iDSL、Java8の大部分、そして古き良きStringBuilderはすべて、長いチェーンを構築するためのものです。チェーン内のすべてが連携して動作することを意図しており、連携し続けることを約束されているため、彼らはLoDに違反しません。互いに聞いたことのないものをつなぎ合わせると、デメテルに違反します。友人とは、あなたのチェーンが機能し続けることを約束した友人です。Friends of Friendsはしませんでした。
ファクトリクラスやビルダークラスなど、オブジェクトを返すように特別に指定されたクラスは別として、メソッドがオブジェクト、クラスのプロパティの1つによって保持されているオブジェクト、またはデメテルの法則に違反するオブジェクトを返すことは問題ありませんか(1) ?
これは、デメテルに違反する機会を作り出すだけです。これは違反ではありません。これは必ずしも悪いことではありません。
そして、それがデメテルの法則に違反する場合、返されるオブジェクトがデータの一部を表し、このデータのゲッターのみを含む不変オブジェクトであるかどうかは問題になりますか?
不変は良いですが、ここでは無関係です。長いチェーンを介して物事を取得しても、それは改善されません。それを改善するのは、取得を使用から分離することです。使用している場合は、パラメーターとして必要なものを尋ねます。見知らぬ人のゲッターを掘り下げて探しに行かないでください。
擬似コードで:
デメテルの法則は、上記のようなパターンを禁じていると思います。法律に違反せずにdoSomethingElse()を呼び出せるようにするにはどうすればよいですか(3)。
私が話す前にx.doSomethingElse(a)
、あなたが基本的に書いたことを理解してください
b.getA().doSomething()
現在、LoDはドットを数える練習ではありません。しかし、チェーンを作成するとき、A
(を使用してB
)を取得する方法を知っており、を使用する方法を知っていると言いますA
。まあ今A
とB
あなたがちょうどそれらを一緒に結合されたので、親しい友人も優れていました。
あなただけの手に何かを求めていた場合は、A
ことのようにあなたが使用することができA
、それはから来て、どこ世話をしなかったであろうB
になって人生の幸せとあなたの強迫観念の自由を生きることができA
からB
。
x.doSomethingElse(a)
どこの詳細なしx
から来た、LODはそれについて言うことは全く何の関係もありません。
LoDは、使用を構造から分離することを促進できます。しかし、すべてのオブジェクトを親しみのないものとして宗教的に扱うと、静的メソッドでコードを書くのにこだわることになります。このようにメインの素晴らしく複雑なオブジェクトグラフを構築できますが、最終的には、動作を開始するためにメソッドを呼び出す必要があります。あなたは単にあなたの友人が誰であるかを決定する必要があります。それから逃れることはできません。
そのため、クラスはLoDの下でメンバーの1つを返すことができます。その場合、そのメンバーがクラスに友好的かどうかを明確にする必要があります。そうでない場合、一部のクライアントは、使用する前にそれを取得することでそのクラスに結合しようとする場合があります。これは重要です。なぜなら、返されるものは常にその使用をサポートする必要があるからです。
多くの場合、これは単に懸念事項ではありません。コレクションは、それらを使用するすべてのものと友達になることを意図しているため、単にこれを無視できます。同様に、値オブジェクトは誰にとっても使いやすいです。しかし、住所を要求するのではなく、住所を抽出する従業員オブジェクトを要求する住所検証ユーティリティを作成した場合、従業員と住所の両方が同じライブラリからのものであることを願っています。