DesignPattern Series __06 Dmitry principle

Dmitry principles defined

Dmitry principle, also known as the least known principle that a class should own dependent class know as little as possible , while being dependent on how complex your class does not matter to me. That is, for other dependent classes, no matter how complex business logic, should try encapsulated within the class; in addition to the external public methods essential, not divulge any information.

1. The origin of the problem

We know that the classes and there is a coupling relationship between the closer the relationship between the two classes, the greater the coupling relationship.

2. countermeasures

Dimitris principle requires: a direct communication with friends and classes should only between.

1. The definition of direct friends

In the above we referred to the "direct friend" concept, in fact, in a program object, every class and other classes will have coupling relationship, otherwise there is no need to exist. Coupling mode comprising: dependent, associated, combined, polymerization and the like. We say that there is a relationship between two classes coupling relationship is friendship.
So, what is the "direct friend" mean?
For example, classes A and B having a coupling relationship, if the Class A Class B as a member variable, method parameter, return value, said two classes is a direct friend; as Class A if the local variable within the method of the class B direct the class a friend is not a class B. In other words, unfamiliar class best not to appear within the class in the form of local variables.

3. Application of

Dimitris principle requires us to do the following four points:

1. direct and communicate with friends only

To illustrate this point, we need an example: for example, there are various colleges within a university, we are now required to print out each college and school staff ID headquarters. The following code demonstrates:

 public class Demeter1 {
    public static void main(String[] args) {
        SchoolManager schoolManager = new SchoolManager();
        schoolManager.printAllEmp(new CollegeManager());
    }
}

class SchoolManager {
    public void printAllEmp(CollegeManager collegeManager) {
        List<Employee> empList = this.getAllEmployee();
        System.out.println("打印学校总部的员工");
        for (Employee employee: empList) {
            employee.printId();
        }
         //分析问题
    //1. 这里的 CollegeEmployee 不是  SchoolManager的直接朋友
    //2. CollegeEmployee 是以局部变量方式出现在 SchoolManager
        //3. 违反了 迪米特法则 
        List<CollegeEmployee> collegeEmpList = collegeManager.getAllEmployee();
        System.out.println("打印学院员工");
        for (CollegeEmployee collegeEmployee: collegeEmpList) {
            collegeEmployee.printId();
        }
    }

    //返回所用总部信息
    public List<Employee> getAllEmployee() {
        List<Employee> list = new ArrayList<>();
        //添加5名总部的员工
        for (int i=0; i<5;i++) {
            Employee employee = new Employee();
            employee.setId(i);
            list.add(employee);
        }
        return list;
    }
}

//学院员工的管理类
class CollegeManager {
    //返回学院的所有员工
    public List<CollegeEmployee> getAllEmployee() {
        List<CollegeEmployee> list = new ArrayList<>();
        //添加10名学院员工
        for (int i = 0; i < 10; i++) {
            CollegeEmployee emp = new CollegeEmployee();
            emp.setId(i);
            list.add(emp);
        }
        return list;
    }
}

//学校员工类
class Employee {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void printId() {
        System.out.println("学校员工,ID=" + this.getId());
    }
}

//学院员工类
class CollegeEmployee {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void printId() {
        System.out.println("学院员工,ID=" + this.getId());
    }
}

According to the above code, we come to look like SchoolManager direct friends: Employee, CollegeManager, and CollegeEmployee local variable is to appear on the SchoolManager, which violates the "principle of Demeter."

improvement measures

That being the case, we will be CollegeEmployee pulled out from SchoolManager class, so as not to be dependent.
A printing method for increasing printCollegeEmps college employees in CollegeManager in (), so, SchoolManager would simply call this method on the line.

  public void printCollegeEmps() {
        List<CollegeEmployee> list = this.getAllEmployee();
        for (CollegeEmployee collegeEmployee: list) {
            collegeEmployee.printId();
        }
    }

2. friends have to keep an appropriate distance

Here you can see the confusion, since it has asked us to do: a class and directly communicate with friends only, so why keep a distance from it? Or example: There are two classes A, B, Class A has three public methods, three methods need to call the class B in A to a complete process:

public class Demeter2 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        b.invokerA(a);
    }
}

class A {
    public void method1() {
        System.out.println("执行第一个方法");
    }

    public void method2() {
        System.out.println("执行第二个方法");
    }

    public void method3() {
        System.out.println("执行第三个方法");
    }

}

class B {
    public void invokerA(A a) {
        System.out.println("调用A的buildMethod()...");
        a.method1();
        a.method2();
        a.method3();
    }
}

The OK, the function is completed, however, class B requires three turn calls for class A, the method needs three holding class B are visible. In other words, the coupling of Class B and Class A is too high , we can improve the look of the relationship between the two, at a modest reduction in the degree of coupling. Definition of a public methods in a class A, class B logic package, the rest of the method is set to private.

 //类A的相应修改
 private void method1() {
        System.out.println("执行第一个方法");
    }

    private void method2() {
        System.out.println("执行第二个方法");
    }

    private void method3() {
        System.out.println("执行第三个方法");
    }

    public void buildMethod() {
        System.out.println("流程开始");
        method1();
        method2();
        method3();
        System.out.println("流程结束");
    }

3. is their own

When a method in this class and other classes can be, then, if, a method in this class, does not increase the degree of coupling between classes, it will not cause adverse effects in this category .

4. caution Serializable

For example, when a passing object using RMI VO manner in a project, the object must implement Serializable, it is serialized. When you suddenly client access to the VO object to change when the public from the private, and the server no corresponding change, there will be mistakes.

Guess you like

Origin www.cnblogs.com/JackHou/p/11311107.html