1. 概念
- 迪米特法則(Demeter Principle)又叫最少知道原則,即一個類對自己依賴的類知道的越少越好。
- 迪米特法則還有個更簡單的定義:只與直接的朋友通信
- 朋友:有耦合(依賴,關(guān)聯(lián),組合,聚合)關(guān)系的對象
- 直接的朋友:成員變量,方法參數(shù),方法返回值中的類
2. 優(yōu)點
- 降低耦合性,提高模塊功能的獨立性
- 非常實用,能直接用于開發(fā)環(huán)境
3. 代碼示例
示例1(違背迪米特法則的案例)
package com.bz.design.principle.demeter;
import java.util.ArrayList;
import java.util.List;
// 客戶端
public class Demeter001 {
public static void main(String[] args) {
//創(chuàng)建了一個SchoolManager對象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id和學(xué)校總部的員工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
// 總部員工
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
// 學(xué)院員工
class CollegeEmployee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
// 管理學(xué)院員工的類
class CollegeManager {
// 返回學(xué)院的所有員工
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院員工id=" + i);
list.add(emp);
}
return list;
}
}
// 學(xué)校管理類
// 分析 SchoolManager 類的直接朋友 Employee、CollegeManager
// CollegeEmployee 不是直接朋友,違反了迪米特法則
class SchoolManager {
// 返回學(xué)??偛康膯T工
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("學(xué)??偛繂T工id=" + i);
list.add(emp);
}
return list;
}
// 該方法完成輸出學(xué)校總部和學(xué)院員工信息的方法
void printAllEmployee(CollegeManager sub) {
// 分析問題
// 1.這里的CollegeEmployee 不是SchoolManager的直接朋友
// 2.CollegeEmployee 是以局部變量方式出現(xiàn)在SchoolManager
// 3.違反了迪米特法則
List<CollegeEmployee> list1 = sub.getAllEmployee();
System.out.println("----------學(xué)院員工----------");
for (CollegeEmployee e : list1) {
System.out.println(e.getId());
}
List<Employee> list2 = this.getAllEmployee();
System.out.println("------------學(xué)??偛繂T工------------");
for (Employee e : list2) {
System.out.println(e.getId());
}
}
}
示例2
- 應(yīng)用實例改進
- 前面設(shè)計的問題在于SchoolManager中,CollegeEmployee類并不不是SchoolManager類的直接朋友(分析)
- 按照迪米特法則,應(yīng)該避免類中出現(xiàn)這樣非直接朋友關(guān)系的耦合
- 對代碼按照迪米特法則進行改進
package com.bz.design.principle.demeter.improve;
import java.util.ArrayList;
import java.util.List;
/**
* 應(yīng)用實例改進
* 1)前面設(shè)計的問題在于SchoolManager中,CollegeEmployee類并不不是SchoolManager類的直接朋友(分析)
* 2)按照迪米特法則,應(yīng)該避免類中出現(xiàn)這樣非直接朋友關(guān)系的耦合
* 3)對代碼按照迪米特法則進行改進
*/
public class DemeterImprove {
public static void main(String[] args) {
System.out.println("---使用迪米特法則改進---");
//創(chuàng)建了一個SchoolManager對象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id和學(xué)校總部的員工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
// 總部員工
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
// 學(xué)院員工
class CollegeEmployee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
// 管理學(xué)院員工的類
class CollegeManager {
// 返回學(xué)院的所有員工
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院員工id=" + i);
list.add(emp);
}
return list;
}
// 改進點
// 輸出學(xué)院員工的信息
public void printEmployee() {
// 獲取到學(xué)院員工
List<CollegeEmployee> list1 = this.getAllEmployee();
System.out.println("----------學(xué)院員工----------");
for (CollegeEmployee e : list1) {
System.out.println(e.getId());
}
}
}
// 學(xué)校管理類
class SchoolManager {
// 返回學(xué)??偛康膯T工
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("學(xué)??偛繂T工id=" + i);
list.add(emp);
}
return list;
}
// 該方法完成輸出學(xué)校總部和學(xué)院員工信息的方法
void printAllEmployee(CollegeManager sub) {
// 分析問題
// 將輸出學(xué)院的員工方法,封裝到CollegeManager
sub.printEmployee();
List<Employee> list2 = this.getAllEmployee();
System.out.println("------------學(xué)校總部員工------------");
for (Employee e : list2) {
System.out.println(e.getId());
}
}
}
4. 應(yīng)用注意事項
-
不要干
- objectA.getObjectB().doSomething();
- objectA.getObjectB().getObjectC().doSomething();
-
遵循迪米特法則的設(shè)計模式
- 注意事項
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。