Design principles--the principle of least knowledge

Definition: An object should have minimal knowledge about other objects.

Origin of the problem: The closer the relationship between classes and the greater the coupling, when one class changes, the greater the impact on another class.

Solution: Minimize class-to-class coupling.

         Since we started programming, we have known the general principles of software programming: low coupling, high cohesion. Whether it is procedural programming or object-oriented programming, the code reuse rate can be improved only if the coupling between each module is as low as possible. The advantages of low coupling are self-evident, but how to program to achieve low coupling? That's exactly what the Law of Demeter is trying to accomplish.

         The Law of Demeter, also known as the principle of least known, was first proposed by Ian Holland of Northeastern University in the United States in 1987. In layman's terms, the less a class knows about the classes it depends on, the better. That is to say, for the dependent class, no matter how complicated the logic is, try to encapsulate the logic inside the class as much as possible, and do not leak any information to the outside except for the public methods provided. The Law of Demeter has an even simpler definition: Only communicate with immediate 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, composition, aggregation, etc. Among them, we call the classes that appear in member variables, method parameters, and method return values ​​as direct friends , while classes appearing in local variables are not direct friends. That is to say, unfamiliar classes are best not to appear inside the class in the form of local variables.

         Take an example: There is a group company, and its subordinate units have branches and direct departments. Now it is required to print out the employee IDs of all subordinate units. Let's start with a design that violates the Law of Demeter.

// head office employee
class Employee{
	private String id;
	public void setId(String id){
		this.id = id;
	}
	public String getId(){
		return id;
	}
}

// branch employees
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 the 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 Office"+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());
	}

Now the main problem of this design is in CompanyManager. According to the Law of Demeter, only direct friends communicate with SubEmployee class, while SubEmployee class is not a direct friend of CompanyManager class (coupling with local variables does not belong to direct friends), from the logic As mentioned above, the head office only needs to be coupled with its branch office, and has no connection with the employees of the branch office. This design obviously increases unnecessary coupling. According to the Law of Demeter, such coupling of non-direct 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();
			//Assign an ID to the 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 Office"+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 staff ID is added for the branch, and the head office directly calls it to print, thus avoiding the coupling with the employees of the branch.

        The original intention of the Law of Demeter is to reduce the coupling between classes, since each class reduces unnecessary dependencies, it can indeed reduce the coupling relationship. But there are degrees in everything. Although it is possible to avoid direct communication with the class, 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 are in contact. Excessive use of the Demeter principle will generate a large number of such mediation and transfer classes, resulting in increased system complexity. Therefore, when adopting the Law of Demeter, it is necessary to repeatedly balance, not only achieve a clear structure, but also high cohesion and low coupling.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326417028&siteId=291194637
Recommended