Six principles of design pattern - Dimitri's law

Six principles of design pattern - Dimitri's law

Definition: Dimitri's law is also called the least knowledge principle. An object should have the least understanding of other objects. An English interpretation of Dimitri's law is: Only talk to your immediate friends.

A class should know the least about the class it needs to couple or call. The internal logic of the coupled or called class has nothing to do with itself and does not need to care. It only needs to know the public methods or attribute variables provided by the coupled or called class.

The core idea of dimitt's law is to reduce the coupling between classes. Each class shall minimize the dependence on other classes. Therefore, it is easy to make the functional modules of the system function independently, and there is no (or little) dependence between them.

Dimitri's law in a narrow sense
If two classes do not have to communicate directly with each other, then the two classes should not interact directly. If one class must call some methods of the other class, the call can be forwarded through a third party.

Minimize GetA().GetB().GetC() calls.

Friend definition
(1) The current object itself (this)
(2) The object passed in as a parameter to the current object method
B is a friend of A

    public class A
    {
        public void SetB(B b)
        {   }
    }

    public class B
    {   }

(3) The object directly referenced by the instance variable of the current object
As follows, C refers to the B object. B is a friend of C

    public class B
    {
    }

    public class C
    {
        private B b;
    }

(4) If the instance variable of the current object is an aggregate, the elements in the aggregate are also friends
If the variable cList in class D is an aggregate of class C, all class C objects in the aggregate are friends of class D objects

    public class C
    {
        private B b;
    }

    public class D
    {
        private List<C> cList = new List<C>();
    }

(5) The object created by the current object
Class E object method CreateD() creates a class D object, and the created class D object D is a friend of class E object

    public class D
    {
        private List<C> cList = new List<C>();
    }

    public class E
    {
        public D CreateD()
        {
            D d = new D();
            return d;
        }
    }

Disadvantages of the narrow Dimitri Law:
(1) There are a large number of small methods in the system. These methods are only indirect calls, which have nothing to do with the business logic of the system
(2) Following the Demeter rule between classes will simplify the local design of a system, because each part will not interact with remote objects, but it will also reduce the communication efficiency between different modules of the system, and it will not be easy to coordinate between different modules of the system.

Appearance mode and intermediary mode are the application of Dimitri's law

The embodiment of generalized Demeter's rule in class design:
(1) Give priority to designing a class as an invariant class
(2) Minimize the access rights of a class: for example, limit the access rights of a class to a package and namespace
(3) Minimize the access rights of members: for example, use public, protected and private reasonably

Here's an example to show how to follow Dimitri's law
There is a design company
The person in charge of a department is the project manager, who manages the programmers, artists and product designers in the Department
For a customer, the customer should only be responsible for raising requirements with the project manager, who will arrange work tasks to different personnel according to the requirements

Analogy to Dimitri's law
Friends of the project manager: programmers, artists and product designers
Customer's friend: Project Manager
Customers are strangers to programmers, artists and product designers
Under normal circumstances, customer class objects are not allowed to access and call the objects of programmers, artists and product designers

The code is implemented as follows

// Add namespace and restrict access
namespace Company
{
    // project manager
    public class PM
    {
        // It refers to the program personnel and is not allowed to access this variable through PM object
        private Program _program;
        // It refers to the artist, and the variable is not allowed to be accessed through the PM object
        private Art _art;
        // It refers to product personnel, and it is not allowed to access this variable through PM object
        private Product _product;

        public PM()
        {
            // Create objects directly inside
            Program program = new Program();
            SetProgram(program);

            Art art = new Art();
            SetArt(art);

            Product product = new Product();
            SetProduct(product);
        }

        // Add reference object
        public void SetProgram(Program program)
        {
            _program = program;
        }

        // Add reference object
        public void SetArt(Art art)
        {
            _art = art;
        }

        // Add reference object
        public void SetProduct(Product product)
        {
            _product = product;
        }

        // Demand call
        public void DoSomething(string msg)
        {
            if (msg.CompareTo("programDemand") == 0)
            {
                _program.DoSomething(msg);
            }
            else if (msg.CompareTo("artDemand") == 0)
            {
                _art.DoSomething(msg);
            }
            else if (msg.CompareTo("productDemand") == 0)
            {
                _product.DoSomething(msg);
            }
        }
    }

    // Program personnel
    public class Program
    {
        // Demand call
        public void DoSomething(string msg)
        {
            Console.WriteLine("Program personnel:" + msg);
        }
    }

    // Art personnel
    public class Art
    {
        // Demand call
        public void DoSomething(string msg)
        {
            Console.WriteLine("Art personnel:" + msg);
        }
    }

    // Product designer
    public class Product
    {
        // Demand call
        public void DoSomething(string msg)
        {
            Console.WriteLine("Product designer:" + msg);
        }
    }
}

The customer class is implemented as follows

// Add namespace and restrict access
namespace Client
{
    public class Client
    {
        public Client()
        {
            Company.PM pM = new Company.PM();

            pM.DoSomething("programDemand");
            pM.DoSomething("artDemand");
            pM.DoSomething("productDemand");
        }
    }
}

The test results are as follows

Tags: Design Pattern

Posted on Wed, 01 Dec 2021 16:24:47 -0500 by kazer