デメテルの法則

デメテルの法則 (Law of Demeter, LoD) または最小知識の原則 (Principle of Least Knowledge) とは、ソフトウェアの設計、特にオブジェクト指向プログラムの設計におけるガイドラインである。
このガイドラインは1987年の末にかけてノースイースタン大学で作成された。簡潔に言うと「直接の友達とだけ話すこと」と要約できる。基本的な考え方は、任意のオブジェクトが自分以外（サブコンポーネント含む）の構造やプロパティに対して持っている仮定を最小限にすべきであるという点にある。
「デメテルの法則」という名前は、この法則がアダプティブプログラミングとアスペクト指向プログラミングに関する研究であるデメテルプロジェクトの成果であることに由来する。プロジェクト名は農業の女神であるデーメーテールにあやかっている。
オブジェクト指向における適用.
オブジェクト指向プログラムにデメテルの法則を適用する場合には、この法則はより厳密に「関数/メソッドに関するデメテルの法則」(Law of Demeter for Functions/Methods, LoD-F) と言い表すことができる。この場合、あるオブジェクトAは別のオブジェクトBのサービスを要求してもよい（メソッドを呼び出してもよい）が、オブジェクトAがオブジェクトBを「経由して」さらに別のオブジェクトCのサービスを要求してはならない。これが望ましくないのは、オブジェクトAがオブジェクトBに対して、オブジェクトB自身の内部構造以上の知識を要求してしまうためである。
このような場合には、クラスBを変更し、クラスAがクラスBに対して行った要求を適切なBのサブコンポーネントに伝播させるようにすればよい。または、AがCへのリファレンスを持つようにして、AがCを直接呼ぶようにしてもよい。この法則に従えば、オブジェクトBが知っているのは自分自身の内部構造だけになる。
より形式的に言えば、関数に対するデメテルの法則に従った場合、オブジェクト"O"上のメソッド"M"が呼び出してもよいメソッドは以下のオブジェクトに属するメソッドのみに限定される。
具体的には、他のメソッドの戻り値として返されたオブジェクトのメソッドの呼び出しを避けるということになる。最近のオブジェクト指向言語の多くではフィールド識別子としてドット(.)が採用されているが、そのような言語においてはこの法則は単純に「使えるドットは1つだけ」と言い表すこともできる。つまり、"a.b.Method()"という呼び出しは法則に違反しているが"a.Method()"という呼び出しは問題ない。なお、このアプローチの充足性については反論がある。
簡単な例として、犬を散歩に連れ出すことを考える。この際、犬の足に直接「歩け」と命じるのはおかしいだろう。この場合は、犬に対して命令し、自分の足の面倒は自分で見させるのが正しい方法だといえる。
利点と欠点.
デメテルの法則の利点としては、結果的にソフトウェアがよりメンテナンスしやすく、柔軟なものになりやすいという点が挙げられる。オブジェクトが他のオブジェクトの内部構造に依存することが少なくなるため、オブジェクトのコンテナを呼び出し側の変更なしに修正することができる。
デメテルの法則の欠点としては、時として数多くの"ラッパー"メソッド（デメテルのTransmogrifierと呼ばれる）を作成する必要があるという点が挙げられる。このメソッドは自分自身の呼び出しを別のコンポーネントに委譲するためのものである。さらに、自分自身が含んでいるクラスのメソッドを呼び出せるようにするためにインタフェースが巨大になり、結果としてクラスの凝集度が低下するという欠点もある。
Basiliらによる1996年の実験では、デメテルの法則がソフトウェアの欠陥の発生確率を低下させるのに有効であることが示唆されている。
マルチレイヤアーキテクチャは、ソフトウェアシステムにおいてデメテルの法則を系統的に実装するためのメカニズムとして捉えることができる。
レイヤ化されたアーキテクチャにおいて、各レイヤ中のコードは自分の属するレイヤと直下のレイヤのコードのみを呼び出すことができる。直下のレイヤをスキップして他のレイヤにアクセスした場合には、アーキテクチャに違反していることになる。