デメテルの法則の原理をわかりやすく説明する

デメテルの法則(または最小知識の原則)は、ソフトウェアアプリケーションを開発するための設計ガイドラインです。1987年にノースイースタン大学で最初に議論されたこの原則は、オブジェクトが他のオブジェクトの内部の詳細を決して知らないようにするべきであると述べています。これは、ソフトウェア設計における疎結合を促進するために設計されました。

結合は、ソフトウェアモジュール間に存在する相互依存の程度、およびそのようなモジュールが互いにどれだけ密接に接続されているかとして定義される場合があることに注意してください。アプリケーション内のコンポーネント間の結合が多いほど、時間の経過とともにコンポーネントを変更および維持することが難しくなります。アプリケーション内のコンポーネントが疎結合されていることを確認することで、テストと保守が容易なシステムを設計することは常に良い習慣です。凝集度と結合度について詳しくは、こちらの私の記事をご覧ください。

デメテルの法則の原理を理解する

デメテルの法則の原則は、モジュールが操作するオブジェクトの内部の詳細に関する知識を持つべきではないと述べています。言い換えると、ソフトウェアコンポーネントまたはオブジェクトは、他のオブジェクトまたはコンポーネントの内部動作に関する知識を持ってはなりません。例を挙げてデメテルの法則を理解しましょう。

3つのクラス(A、B、C)と、これらのクラスのオブジェクト(objA、objB、objC)について考えてみます。ここで、objAがobjBに依存し、objBがobjCを構成するとします。このシーンでは、objAはobjBのメソッドとプロパティを呼び出すことができますが、objCは呼び出すことができません。

デメテルの法則の原則は、カプセル化を利用してこの分離を実現し、アプリケーションのコンポーネント間の結合を減らします。これは、コードの品質を向上させ、柔軟性とコードのメンテナンスを容易にするのに役立ちます。デメテルの法則を順守することの利点は、保守が容易で将来の変更に適応できるソフトウェアを構築できることです。

メソッドMを持つクラスCについて考えてみます。ここで、Oという名前のクラスCのインスタンスを作成したとします。デメテルの法則では、メソッドMが次のタイプを呼び出すことができるか、クラスのプロパティが次のタイプを呼び出す必要があると指定されています。メンバーのみ:

  • 同じオブジェクト、つまりオブジェクト「O」自体
  • メソッド「M」に引数として渡されたオブジェクト
  • ローカルオブジェクト、つまりメソッド「M」内で作成されたオブジェクト
  • オブジェクト「O」からアクセスできるグローバルオブジェクト
  • オブジェクト「O」の直接コンポーネントオブジェクト

これは、デメテルの法則の原則に準拠するクラスとそのメンバーを示すコードリストです。わかりやすくするために、該当する場合はいつでもコメントに言及しました。

public class LawOfDemeterExample

    {

        //This is an instance in the class scope

        //and hence this instance can be accessed by any members of this class

        AnotherClass instance = new AnotherClass();

       public void SampleMethodFollowingLoD(Test obj)

        {         

            DoNothing(); //This is a valid call as you are calling a method of the same class

             object data = obj.GetData(); //This is also valid since you are calling a method

            //on an instance that has been passed as a parameter           

             int result = instance.GetResult();  //This is also a valid call as you are calling

            //a method on an instance locally created

        }

        private void DoNothing()

        {

            // Write some code here

        }

    }

上記のコードをコンパイルするために必要な他の2つのクラスは次のとおりです。

public class AnotherClass

    {

        public int GetResult()

        {

            return -1;

        }

    }

    public class Test

    {

        public object GetData()

        {

            return null;

        }

    }

ここで、上記のLawOfDemeterExampleクラスを参照してください。コードは一目瞭然です。デメテルの法則がメソッドにのみ適用されるのかどうか疑問に思うかもしれません。答えはいいえだ"。デメテルの法則の原則は、プロパティにも適用されます。

デメテルの法則の原則違反

前に説明した最初のコード例では、デメテルの法則の原則を順守することから、このトピックに関する議論を開始しました。この原則に従わないとどうなるかを理解しましょう。このコード例を考えてみましょう。

var data = new A().GetObjectB().GetObjectC().GetData();

この例では、クライアントはクラスA、B、およびCに依存する必要があります。つまり、クライアントはクラスA、B、およびCのインスタンスに結合されます。将来これらのクラスが変更された場合、次のような問題が発生します。将来、これらのクラスのいずれかで発生する可能性のある変更に自分自身をさらしています。