天天看點

07迪米特法則基本介紹代碼示例注意和細節

基本介紹

1、一個對象應該對其他對象保持最少了解,也就是說一個實體應該盡量少的與其他實體之間發生互相作用,使得系統功能子產品相對獨立。

2、類與類關系越密切,耦合度越大

3、迪米特法則又叫最少知道原則,即一個類對自己依賴的類知道得越少越好。也就是說,對于被依賴的類不管多複雜,都盡量将邏輯封裝在類的内部。除了對外提供public方法,不對外洩露任何資訊。

4、迪米特法則還有個更簡單的定義:隻與直接朋友通信

5、直接朋友:每個對象都與其他對象有耦合關系,隻要兩個對象之間有耦合關系,我們就說這兩個對象之間是朋友關系。耦合的方式很多,依賴、關聯、組合、聚合等。其中,我們稱出現成員變量,方法參數,方法傳回值中的類為直接朋友,而出現在局部變量中的類不是直接朋友。也就是說,陌生的類最好不要以局部變量的形式出現在類的内部。

這裡解釋一下第5條:假設有對象A和對象B,如果對象B是對象A的成員變量(public B b;),那麼A 和 B對象就是直接朋友;假設對象A中有方法m(),當對象B是方法m()的參數(m(B b)),或者是方法m()的傳回值(return B;)時,A和B對象也是直接朋友。但如果方法m()中出現了B b = new B();這樣的代碼,B為方法m()的局部變量,A和B對象就不是直接朋友關系。

代碼示例

需求:有一個學校,下屬有各個學院和總部,現要求列印出學校總部員工ID和學院員工ID。

public class Demeter01 {
    public static void main(String[] args) {
        // 建立了一個SchoolManager對象
        SchoolManager schoolManager = new SchoolManager();
        // 輸出學院的的員工ID和總部的員工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 < 5; i++) {
            CollegeEmployee employee = new CollegeEmployee();
            employee.setId("學院員工的id = " + i);
            list.add(employee);
        }
        return list;
    }
}

class SchoolManager {
    public List<Employee> getAllEmployee() {
        List<Employee> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Employee employee = new Employee();
            employee.setId("學校總部員工的id = " + i);
            list.add(employee);
        }
        return list;
    }

    /**
     * 該方法完成輸出學校總部和學院員工資訊
     * @param collegeManager
     */
    void printAllEmployee(CollegeManager collegeManager) {
        // 擷取到學院員工
        List<CollegeEmployee> list1 = collegeManager.getAllEmployee();
        System.out.println("------學院員工-------");
        for (CollegeEmployee employee : list1) {
            System.out.println(employee.getId());
        }
        // 擷取到總部員工
        List<Employee> list2 = this.getAllEmployee();
        System.out.println("-----總部員工-------");
        for (Employee employee : list2) {
            System.out.println(employee.getId());
        }
    }
}
           

輸出結果:

------學院員工-------
學院員工的id = 0
學院員工的id = 1
學院員工的id = 2
學院員工的id = 3
學院員工的id = 4
-----總部員工-------
學校總部員工的id = 0
學校總部員工的id = 1
學校總部員工的id = 2
           

分析SchoolManager類的直接朋友有哪些?

Employee類是getAllEmployee()方法的傳回值,是以是直接朋友;

CollegeManager類是printAllEmployee()方法的參數,是以是直接朋友。

CollegeEmployee是printAllEmployee方法的局部變量,不是通過方法參數傳遞進來的,是以不是直接朋友,是一個陌生類,違反了迪米特法則。

改進思路:

1、前面設計的問題在于SchoolManager中,CollegeEmployee類并不是SchoolManager類的直接朋友

2、按照迪米特法則,應該避免類中出現這樣的非直接朋友關系的耦合。

public class Demeter02 {
    public static void main(String[] args) {
        // 建立了一個SchoolManager對象
        SchoolManager02 schoolManager = new SchoolManager02();
        // 輸出學院的的員工ID和總部的員工ID
        schoolManager.printAllEmployee(new CollegeManager02());

    }
}

/**
 * 學院員工類
 */
class Employee02 {
    private String id;

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

    public String getId() {
        return id;
    }
}

/**
 * 學院員工類
 */
class CollegeEmployee02 {
    private String id;

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

    public String getId() {
        return id;
    }
}

/**
 * 管理學院員工的管理類
 */
class CollegeManager02 {
    public List<CollegeEmployee02> getAllEmployee() {
        List<CollegeEmployee02> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            CollegeEmployee02 employee = new CollegeEmployee02();
            employee.setId("學院員工的id = " + i);
            list.add(employee);
        }
        return list;
    }

    /**
     * 輸出學院員工的資訊
     */
    public void printEmployee() {
        List<CollegeEmployee02> list = this.getAllEmployee();
        System.out.println("------學院員工-------");
        for (CollegeEmployee02 employee : list) {
            System.out.println(employee.getId());
        }
    }
}

class SchoolManager02 {
    public List<Employee02> getAllEmployee() {
        List<Employee02> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Employee02 employee = new Employee02();
            employee.setId("學校總部員工的id = " + i);
            list.add(employee);
        }
        return list;
    }

    /**
     * 該方法完成輸出學校總部資訊
     */
    void printAllEmployee(CollegeManager02 collegeManager) {
        // 輸出學院的員工方法 封裝到CollegeManager02
        collegeManager.printEmployee();

        // 擷取到總部員工
        List<Employee02> list1 = this.getAllEmployee();
        System.out.println("-----總部員工-------");
        for (Employee02 employee : list1) {
            System.out.println(employee.getId());
        }
    }
}
           

輸出結果:

------學院員工-------
學院員工的id = 0
學院員工的id = 1
學院員工的id = 2
學院員工的id = 3
學院員工的id = 4
-----總部員工-------
學校總部員工的id = 0
學校總部員工的id = 1
學校總部員工的id = 2
           

注意和細節

1、迪米特法則的核心是降低類之間的耦合

2、但是注意:每個類都減少了不必要的依賴,是以迪米特法則隻是要求降低類之間(對象間)耦合關系,并不是要求完全沒有依賴關系。

繼續閱讀