Design pattern principle
1. Overview
- One object should have the least knowledge of other objects
- The closer the relationship between class and class, the greater the coupling degree
- Demeter principle is also known as the least known principle, that is, the less a class knows about its own dependent classes, the better. In other words, no matter how complex the dependent class is, try to encapsulate the logic inside the class. In addition to the public method provided, no information is disclosed to the public
- Dimiter's law also has a simpler definition: only communicate with direct friends
- Direct friend: every object has 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 the class in the occurrence member variable, method parameter and method return value as the direct friend, while the class in the local variable is not the direct friend. That is to say, it is better not to appear in the form of local variables in a strange class.
2. Issue
There is a school with subordinate schools and headquarters. Now it is required to print out the ID of the staff in the school headquarters and the ID of the staff in the school
package com.atguigu.principle.demeter; import java.util.ArrayList; import java.util.List; //client public class Demeter1 { public static void main(String[] args) { //Created a SchoolManager object SchoolManager schoolManager = new SchoolManager(); //Output the employee id of the college and the employee information of the school headquarters schoolManager.printAllEmployee(new CollegeManager()); } } //Staff of school headquarters class Employee { private String id; public void setId(String id) { this.id = id; } public String getId() { return id; } } //Staff of the College class CollegeEmployee { private String id; public void setId(String id) { this.id = id; } public String getId() { return id; } } //Management of the staff of the school of management class CollegeManager { //All employees returning to the College public List<CollegeEmployee> getAllEmployee() { List<CollegeEmployee> list = new ArrayList<CollegeEmployee>(); for (int i = 0; i < 10; i++) { //Here we add 10 employees to the list CollegeEmployee emp = new CollegeEmployee(); emp.setId("College staff id= " + i); list.add(emp); } return list; } } //School management //Analyze which Employee and CollegeManager are the direct friend classes of the SchoolManager class //The CollegeEmployee is not a direct friend, but a strange class, which violates Dimitar's law class SchoolManager { //Staff returning to school headquarters public List<Employee> getAllEmployee() { List<Employee> list = new ArrayList<Employee>(); for (int i = 0; i < 5; i++) { //Here we add 5 employees to the list Employee emp = new Employee(); emp.setId("Staff of school headquarters id= " + i); list.add(emp); } return list; } //This method can output the information (id) of school headquarters and college employees void printAllEmployee(CollegeManager sub) { //Analyze problems //1. The CollegeEmployee here is not a direct friend of SchoolManager //2. The collegeemployee appears in the SchoolManager as a local variable //3. Violation of Dimitar's law //Access to college staff List<CollegeEmployee> list1 = sub.getAllEmployee(); System.out.println("------------College staff------------"); for (CollegeEmployee e : list1) { System.out.println(e.getId()); } //Access to school headquarters staff List<Employee> list2 = this.getAllEmployee(); System.out.println("------------Staff of school headquarters------------"); for (Employee e : list2) { System.out.println(e.getId()); } } }
3. Improvement
- The problem of the previous design is that the SchoolManager, the CollegeEmployee class is not a direct friend of the SchoolManager class (analysis)
- According to Dimiter's law, such coupling of indirect friend relationships should be avoided in the class
- Improve the code according to Dimitar's law
package com.atguigu.principle.demeter.improve; import java.util.ArrayList; import java.util.List; //client public class Demeter1 { public static void main(String[] args) { System.out.println("~~~The improvement of using Dimiter's law~~~"); //Created a SchoolManager object SchoolManager schoolManager = new SchoolManager(); //Output the employee id of the college and the employee information of the school headquarters schoolManager.printAllEmployee(new CollegeManager()); } } //School headquarters staff class Employee { private String id; public void setId(String id) { this.id = id; } public String getId() { return id; } } //Staff of the College class CollegeEmployee { private String id; public void setId(String id) { this.id = id; } public String getId() { return id; } } //Management of the staff of the school of management class CollegeManager { //All employees returning to the College public List<CollegeEmployee> getAllEmployee() { List<CollegeEmployee> list = new ArrayList<CollegeEmployee>(); for (int i = 0; i < 10; i++) { //Here we add 10 employees to the list CollegeEmployee emp = new CollegeEmployee(); emp.setId("College staff id= " + i); list.add(emp); } return list; } //Output information of college staff public void printEmployee() { //Access to college staff List<CollegeEmployee> list1 = getAllEmployee(); System.out.println("------------College staff------------"); for (CollegeEmployee e : list1) { System.out.println(e.getId()); } } } //School management //Analyze which Employee and CollegeManager are the direct friend classes of the SchoolManager class //The CollegeEmployee is not a direct friend, but a strange class, which violates Dimitar's law class SchoolManager { //Staff returning to school headquarters public List<Employee> getAllEmployee() { List<Employee> list = new ArrayList<Employee>(); for (int i = 0; i < 5; i++) { //Here we add 5 employees to the list Employee emp = new Employee(); emp.setId("Staff of school headquarters id= " + i); list.add(emp); } return list; } //This method can output the information (id) of school headquarters and college employees void printAllEmployee(CollegeManager sub) { //Analyze problems //1. Encapsulate the employee method of the output college into the CollegeManager sub.printEmployee(); //Access to school headquarters staff List<Employee> list2 = this.getAllEmployee(); System.out.println("------------Staff of school headquarters------------"); for (Employee e : list2) { System.out.println(e.getId()); } } }
4. Precautions and details of Dimitar's law
- The core of Dimiter's law is to reduce the coupling between classes
- But note: because each class reduces unnecessary dependency, Dimitar's law only requires reducing coupling between classes (objects), not no dependency at all