This article mainly introduces the Law of Demeter. The Law of Demeter is a rule that needs to be followed when creating methods and properties in a class. Those who are interested can learn about it
Definition: 1 objects should keep minimal knowledge of other objects.
Origin of the problem: The closer the relationship between classes is, the greater the degree of coupling. When one class changes, the greater the impact on the other class.
Solution: Try to reduce the coupling between classes.
Since we came into contact with programming, we have known the general principles of software programming: low coupling and high cohesion. Whether it is process-oriented programming or object-oriented programming, only by keeping the coupling between modules as low as possible can the code reuse rate be improved. The advantages of low coupling are self-evident, but how can we achieve low coupling through programming? That's exactly what Demeter's Law is meant to accomplish.
Demit's Law, also known as the least-known principle, was first proposed in 1987 by Ian Holland of Northeastern University in the United States. In layman's terms, the less a class knows about the classes it depends on, the better. In other words, for the dependent class, no matter how complex the logic is, the logic should be encapsulated inside the class as much as possible, and no information will be leaked to the outside except the public methods provided. Demeter's Law has a simpler definition: only communicate with direct friends. First, let’s explain what a direct friend is: each object will have a coupling relationship with other objects. As long as there is a coupling relationship between two objects, we say that the two objects are friends. There are many ways of coupling, such as dependency, association, combination, aggregation, etc. Among them, we call classes that appear in member variables, method parameters, and method return values direct friends, while classes that appear in local variables are not direct friends. In other words, it is best not for unfamiliar classes to appear inside the class as local variables.
Give an example: There is a group company whose subordinate units include branches and directly subordinate departments. Now it is required to print out the employee IDs of all subordinate units. Let’s first look at designs that violate Demeter’s Law.
//总公司员工 class Employee{ private String id; public void setId(String id){ this.id = id; } public String getId(){ return id; } } //分公司员工 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(); //为分公司人员按顺序分配一个ID emp.setId("分公司"+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(); //为总公司人员按顺序分配一个ID emp.setId("总公司"+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 with this design now lies in CompanyManager. According to Dimit's Law, communication only occurs with direct friends, and the SubEmployee class is not CompanyManager. Direct friends of the class (couplings that appear in the form of local variables are not direct friends). Logically speaking, the head office only needs to be coupled with its branches, and has no contact with the employees of the branches. This design obviously adds a lot of trouble. Necessary coupling. According to Demeter's Law, such couplings with indirect friend relationships in classes should be avoided. 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(); //为分公司人员按顺序分配一个ID emp.setId("分公司"+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(); //为总公司人员按顺序分配一个ID emp.setId("总公司"+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, a method for printing personnel IDs is added to the branch, and the head office directly calls it to print, thus avoiding the need for communication with the branch. Employees are coupled.
The original intention of Dimit's Law is to reduce the coupling between classes. Since each class reduces unnecessary dependencies, it can indeed reduce the coupling relationship. But everything has its limits. Although indirect communication can be avoided, communication must occur through an "intermediary". For example, in this example, the head office communicates with the branch through the "intermediary" of the branch. employees were contacted. Excessive use of the Demeter principle will produce a large number of such intermediary and transfer classes, resulting in increased system complexity. Therefore, when adopting Dimit's Law, you must repeatedly weigh the trade-offs to achieve both a clear structure and high cohesion and low coupling.
The above is the detailed content of Detailed explanation of Demeter's Law in Java. For more information, please follow other related articles on the PHP Chinese website!