Demistyfikacja zasady Prawa Demeter

Prawo Demetera (lub zasada najmniejszej wiedzy) to wytyczne projektowe dotyczące tworzenia aplikacji. Zasada ta, po raz pierwszy omówiona na Northeastern University w 1987 roku, głosi, że obiekt nigdy nie powinien znać wewnętrznych szczegółów innych obiektów. Został zaprojektowany, aby promować luźne powiązania w projektach oprogramowania.

Należy zauważyć, że sprzężenie można zdefiniować jako stopień współzależności istniejącej między modułami oprogramowania i stopień, w jakim takie moduły są ze sobą połączone. Im większe sprzężenie między komponentami w aplikacji, tym trudniej jest je modyfikować i utrzymywać w czasie. Dobrą praktyką jest zawsze projektowanie systemów, które są łatwiejsze do testowania i konserwacji, zapewniając luźne powiązanie komponentów aplikacji. Możesz dowiedzieć się więcej o spójności i sprzężeniu z mojego artykułu tutaj.

Zrozumienie zasady Demeter

Zasada Prawa Demetera mówi, że moduł nie powinien mieć wiedzy o wewnętrznych szczegółach obiektów, którymi manipuluje. Innymi słowy, komponent oprogramowania lub obiekt nie powinien mieć wiedzy o wewnętrznym działaniu innych obiektów lub komponentów. Rozumiemy prawo Demeter na przykładzie.

Rozważmy trzy klasy, a mianowicie - A, B i C - oraz obiekty tych klas - odpowiednio objA, objB i objC. Teraz załóżmy, że objA jest zależne od objB, co z kolei składa się z objC. W tym scenariuszu objA może wywoływać metody i właściwości objB, ale nie objC.

Zasada Prawa Demetera wykorzystuje hermetyzację, aby osiągnąć tę izolację i zmniejszyć sprzężenie między komponentami aplikacji. Pomaga to w poprawianiu jakości kodu i promuje elastyczność oraz łatwiejszą konserwację kodu. Korzyść z przestrzegania prawa Demeter polega na tym, że można tworzyć oprogramowanie, które jest łatwe w utrzymaniu i dostosowuje się do przyszłych zmian.

Rozważmy klasę C mającą metodę M. Teraz załóżmy, że utworzyłeś instancję klasy C o nazwie O. Prawo Demeter określa, że ​​metoda M może wywoływać następujące typy. Lub właściwość klasy powinna wywoływać następujący typ tylko członków:

  • Ten sam przedmiot, czyli sam obiekt „O”
  • Obiekty, które zostały przekazane jako argument do metody „M”
  • Obiekty lokalne, czyli obiekty, które zostały utworzone w ramach metody „M”
  • Obiekty globalne dostępne dla obiektu „O”
  • Bezpośrednie obiekty składowe obiektu „O”

Oto lista kodu, która ilustruje klasę i jej członków, zgodnie z zasadą Prawa Demeter. Wspominałem o komentarzach wszędzie tam, gdzie ma to zastosowanie, dla przejrzystości.

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

        }

    }

Oto dwie inne klasy, które będą potrzebne do skompilowania powyższego kodu.

public class AnotherClass

    {

        public int GetResult()

        {

            return -1;

        }

    }

    public class Test

    {

        public object GetData()

        {

            return null;

        }

    }

Teraz odwołaj się do klasy LawOfDemeterExample pokazanej powyżej. Kod nie wymaga objaśnień. Możesz się teraz zastanawiać, czy prawo Demeter dotyczy tylko metod. Odpowiedź brzmi nie". Zasada Prawa Demetera ma również zastosowanie do własności.

Naruszenie prawa Demeter

W pierwszym przykładzie kodu wyjaśnionym wcześniej rozpoczęliśmy dyskusję na ten temat od przestrzegania zasady Prawa Demeter. Zrozummy, co się dzieje, gdy nie przestrzegamy tej zasady. Rozważmy ten przykład kodu.

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

W tym przykładzie klient będzie musiał polegać na klasach A, B i C. Innymi słowy, jest połączony z wystąpieniami klas A, B i C.Jeśli w przyszłości te klasy się zmienią, wpadniesz w kłopoty, ponieważ narażasz się na zmiany, które mogą nastąpić na którejkolwiek z tych klas w przyszłości.