1. 1.一个对象应该对其他对象保持最少的了解
    2. 2.类与类关系越密切,耦合度越大
    3. 3.迪米特法则(Demeter Principle)又叫最少知道原则
    4. 4.简单定义:只与直接的朋友通信

    直接朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等,其中,我们称出现成员变量,方法参数,方法返回值中的类为直接朋友.陌生的类最好不要以局部变量的方式出现在类的内部

    迪米特法则注意事项和细节
    1.迪米特法则的核心是降低类之间的耦合
    2.但是注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系

    有一个学校,下属有各个学院和总部,现要求打印出学校总部员工ID和学院员工ID
    代码演示:

    package com.cedric.principle.demeter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    // 客户端
    public class Demeter01 {
        public static void main(String[] args) {
            // 创建了一个SchoolManager对象
            SchoolManager schoolManager = new SchoolManager();
            // 输出学院的员工id和学校总部的员工信息
            schoolManager.printAllEmployee(new CollegeManager());
        }
    }
    
    // 学校总部员工类
    class Employee{
        private String id;
    
        public void setId(String id){
            this.id = id;
        }
    
        public String getId(){
            return id;
        }
    }
    
    // 学院员工类
    class CollegeEmployee{
        private String id;
    
        public void setId(String id){
            this.id = id;
        }
    
        public String getId(){
            return id;
        }
    }
    
    // 管理学院员工的管理类
    class CollegeManager{
        // 返回学院的所有员工
        public List<CollegeEmployee> getAllEmployee(){
            List<CollegeEmployee> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                CollegeEmployee emp = new CollegeEmployee();
                emp.setId("学院员工id =" + i);
                list.add(emp);
            }
            return list;
        }
    }
    
    // 学校管理类
    
    // 直接朋友:Employee、CollegeManager
    // CollegeEmployee不是直接朋友,这样违背了迪米特法则
    class SchoolManager{
        // 返回学校总部的员工
        public List<Employee> getAllEmployee(){
            List<Employee> list = new ArrayList<>();
    
            for (int i = 0; i < 5; i++) { // 这里增加了5个员工到list
                Employee emp = new Employee();
                emp.setId("学校总部的员工id=" + i);
                list.add(emp);
            }
            return list;
        }
    
        // 该方法完成输出学校总部和学院员工信息的方法(id)
        void printAllEmployee(CollegeManager sub){
    
            /*
                分析问题:
                    1.这里的CollegeEmployee不是SchoolManager的直接朋友
                    2.CollegeEmployee是以局部变量的方式出现在SchoolManager
                    3.违反了迪米特法则
             */
            // 获取到学院员工
            List<CollegeEmployee> list1 = sub.getAllEmployee();
            System.out.println("================学院员工=====================");
            for(CollegeEmployee employee : list1){
                System.out.println(employee.getId());
    
            }
            //获取到学校总部员工
            List<Employee> employees = this.getAllEmployee();
            System.out.println("=================学院总部员工=================");
            for(Employee employee : employees){
                System.out.println(employee.getId());
            }
        }
    }
    
    前面设计的问题在于SchoolManager中,CollegeEmployee类并不是SchoolManager类的直接朋友
    按照迪米特法则,应避免类中出现这样非直接朋友关系的耦合
    

    按照迪米特法则改进:

    package com.cedric.principle.demeter.improve;
    
    import java.util.ArrayList;
    import java.util.List;
    
    // 客户端
    public class Demeter01 {
        public static void main(String[] args) {
            System.out.println("------------使用迪米特法则的改进------------");
            // 创建了一个SchoolManager对象
            SchoolManager schoolManager = new SchoolManager();
            // 输出学院的员工id和学校总部的员工信息
            schoolManager.printAllEmployee(new CollegeManager());
        }
    }
    
    // 学校总部员工类
    class Employee{
        private String id;
    
        public void setId(String id){
            this.id = id;
        }
    
        public String getId(){
            return id;
        }
    }
    
    // 学院员工类
    class CollegeEmployee{
        private String id;
    
        public void setId(String id){
            this.id = id;
        }
    
        public String getId(){
            return id;
        }
    }
    
    // 管理学院员工的管理类
    class CollegeManager{
        // 返回学院的所有员工
        public List<CollegeEmployee> getAllEmployee(){
            List<CollegeEmployee> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                CollegeEmployee emp = new CollegeEmployee();
                emp.setId("学院员工id =" + i);
                list.add(emp);
            }
            return list;
        }
        // 输出员工信息
        public void printEmployee(){
            List<CollegeEmployee> list1 = this.getAllEmployee();
            System.out.println("================学院员工=====================");
            for(CollegeEmployee employee : list1){
                System.out.println(employee.getId());
            }
        }
    }
    
    // 学校管理类
    
    // 直接朋友:Employee、CollegeManager
    // CollegeEmployee不是直接朋友,这样违背了迪米特法则
    class SchoolManager{
        // 返回学校总部的员工
        public List<Employee> getAllEmployee(){
            List<Employee> list = new ArrayList<>();
            for (int i = 0; i < 5; i++) { // 这里增加了5个员工到list
                Employee emp = new Employee();
                emp.setId("学校总部的员工id=" + i);
                list.add(emp);
            }
            return list;
        }
    
        // 该方法完成输出学校总部和学院员工信息的方法(id)
        void printAllEmployee(CollegeManager sub){
            // 将输出学院的员工方法,封装到CollegeManager
            sub.printEmployee();
            //获取到学校总部员工
            List<Employee> employees = this.getAllEmployee();
            System.out.println("=================学院总部员工=================");
            for(Employee employee : employees){
                System.out.println(employee.getId());
            }
        }
    }