基本介紹
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、但是注意:每個類都減少了不必要的依賴,是以迪米特法則隻是要求降低類之間(對象間)耦合關系,并不是要求完全沒有依賴關系。