Definition: One object should know the least about other objects
The core concept of Dimitri's law is decoupling between classes and weak coupling. Only after weak coupling can the reusability of classes be improved.
A more vivid metaphor is similar to: prisoners in prison should not contact people outside, of course there may be visiting relatives. The prison here is the class, the prisoners inside are the information inside the class, and the prison guards in the prison are equivalent to the enforcer of the Dimit Law.
Dimit's law claims:
(1) In terms of class division, classes with weak coupling should be created;
(2) In the structure design of the class, each class should minimize the access rights of members;
(3) In the design of a class, if possible, a class should be designed as an unchanged class;
(4) In terms of references to other classes, the references of an object to other objects should be minimized;
(5) Try to minimize access rights to the class;
(6) Use serialization function with caution;
(7) Do not expose class members, but provide the corresponding accessor (properties).
To give an example: there is a group company, and the subordinate units have branches and direct departments. Now it is required to print out the employee IDs of all subordinate units. Let’s first look at the design that violates the Dimit rule.
//Head of the head office class Employee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } } //Branch employee class SubEmployee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } } class SubCompanyManager{ public List<SubEmployee> getAllEmployee(){ List<SubEmployee> list = new ArrayList<SubEmployee>(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //Assign an ID to branch personnel in order emp.setId("Branch"+i); list.add(emp); } return list; } } class CompanyManager{ public List<Employee> getAllEmployee(){ List<Employee> list = new ArrayList<Employee>(); for(int i=0; i<30; i++){ Employee emp = new Employee(); //Assign an ID to the head office personnel in order emp.setId("Head Company"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){ List<SubEmployee> list1 = sub.getAllEmployee(); for(SubEmployee e:list1){ System.out.println(e.getId()); } List<Employee> list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } } public class Client{ public static void main(String[] args){ CompanyManager e = new CompanyManager(); e.printAllEmployee(new SubCompanyManager()); } } The main problem of this design is now in CompanyManager. According to Dimit's law, only communication with direct friends occurs, and the SubEmployee class is not a direct friend of the CompanyManager class (the coupling that appears as local variables does not belong to direct friends). Logically speaking, the head office only needs to be coupled with its branch and has no connection with the branch employees. This design obviously adds unnecessary coupling. According to Dimit's law, such indirect friend relationship coupling should be avoided in the class. The modified code is as follows:
class SubCompanyManager{ public List<SubEmployee> getAllEmployee(){ List<SubEmployee> list = new ArrayList<SubEmployee>(); for(int i=0; i<100; i++){ SubEmployee emp = new SubEmployee(); //Assign an ID to branch personnel in order emp.setId("Branch"+i); list.add(emp); } return list; } public void printEmployee(){ List<SubEmployee> list = this.getAllEmployee(); for(SubEmployee e:list){ System.out.println(e.getId()); } } } class CompanyManager{ public List<Employee> getAllEmployee(){ List<Employee> list = new ArrayList<Employee>(); for(int i=0; i<30; i++){ Employee emp = new Employee(); // Assign an ID to the head office personnel in order emp.setId("Head Company"+i); list.add(emp); } return list; } public void printAllEmployee(SubCompanyManager sub){ sub.printEmployee(); List<Employee> list2 = this.getAllEmployee(); for(Employee e:list2){ System.out.println(e.getId()); } } } After the modification, the method of printing the personnel ID was added to the branch, and the head office directly called it to print, thus avoiding coupling with the branch employees.
The original intention of the Dimitter law is to reduce coupling between classes. Since each class reduces unnecessary dependencies, it is indeed possible to reduce coupling relationships. But everything has its own standards. Although it can avoid communication with indirect types, in order to communicate, you will inevitably contact the branch through an "intermediary". For example, in this case, the head office contacts the branch employees through the branch as the "intermediary". Excessive use of the Dimit principle will result in a large number of such intermediary and transmission classes, resulting in greater system complexity. Therefore, when adopting the Dimitr law, we must repeatedly weigh the trade-offs, which not only ensures clear structure, but also requires high cohesion and low coupling.