迪米特法則
- 一個對象應(yīng)該對其他對象保持最少的了解
- 類與類的關(guān)系越密切,耦合度越大
- 迪米特法則又稱為 最少知道原則,即一個類 對自己依賴的類知道的越少越好挽牢。也就是說,對于被依賴的類不管多么復(fù)雜自阱,都盡量將邏輯封裝在類的內(nèi)部。對外除了提供的 public 方法,不對外泄露任何信息
- 迪米特法則還有個更簡單的定義:只與 直接的朋友通信
- 直接的朋友:每個對象都會與其他對象有 耦合關(guān)系,只要兩個對象之間有耦合關(guān)系绪囱,我們就說這兩個對象之間是朋友關(guān)系。耦合的方式很多莹捡,依賴毕箍,關(guān)聯(lián),組合道盏,聚合等。其中文捶,我們稱出現(xiàn) 成員變量荷逞,方法參數(shù),方法返回值 中的類為直接朋友粹排,而出現(xiàn)在 局部變量中的類不是直接的朋友种远。也就是說,陌生的類最好不要以局部變量的形式出現(xiàn)類的內(nèi)部顽耳。
實例
- 有一個學(xué)校坠敷,下屬有各個學(xué)院和總部,現(xiàn)要求打印出學(xué)猩涓唬總部員工ID 和學(xué)院員工的id
- 代碼實現(xiàn)
public class Demeter1 {
public static void main(String[] args) {
//創(chuàng)建了一個SchoolManager 對象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id 和學(xué)邢ビ總部的員工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
//學(xué)校總部員工類
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//學(xué)院的員工類
class CollegeEmployee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//管理學(xué)院員工的管理類
class CollegeManager {
//返回學(xué)院的所有員工
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) { //這里我們增加了10 個員工到list
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院員工id= " + i);
list.add(emp);
}
return list;
}
}
//學(xué)校管理類
//分析SchoolManager 類的直接朋友類有哪些Employee胰耗、CollegeManager
//CollegeEmployee 不是直接朋友而是一個陌生類限次,這樣違背了迪米特法則
class SchoolManager {
//返回學(xué)校總部的員工
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 5; i++) { //這里我們增加了5 個員工到list
Employee emp = new Employee();
emp.setId("學(xué)校總部員工id= " + i);
list.add(emp);
}
return list;
}
//該方法完成輸出學(xué)新袈總部和學(xué)院員工信息(id)
void printAllEmployee(CollegeManager sub) {
//分析問題
//1. 這里的CollegeEmployee 不是SchoolManager 的直接朋友
//2. CollegeEmployee 是以局部變量方式出現(xiàn)在SchoolManager
//3. 違反了迪米特法則
//獲取到學(xué)院員工
List<CollegeEmployee> list1 = sub.getAllEmployee();
System.out.println("------------學(xué)院員工------------");
for (CollegeEmployee e : list1) {
System.out.println(e.getId());
}
//獲取到學(xué)蟹丫。總部員工
List<Employee> list2 = this.getAllEmployee();
System.out.println("------------學(xué)校總部員工------------");
for (Employee e : list2) {
System.out.println(e.getId());
}
}
}
改進
- 說明
- 前面設(shè)計的問題在于 SchoolManager 中羊始,CollegeEmployee 類并不是SchoolManager 類的直接朋友(分析)
- 按照迪米特法則旱幼,應(yīng)該避免類中出現(xiàn)這樣非直接朋友關(guān)系的耦合
- 代碼
//客戶端
public class Demeter1 {
public static void main(String[] args) {
System.out.println("~~~使用迪米特法則的改進~~~");
//創(chuàng)建了一個SchoolManager 對象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id 和學(xué)校總部的員工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
//學(xué)型晃總部員工類
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//學(xué)院的員工類
class CollegeEmployee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//管理學(xué)院員工的管理類
class CollegeManager {
//返回學(xué)院的所有員工
public List<CollegeEmployee> getAllEmployee() {
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) { //這里我們增加了10 個員工到list
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院員工id= " + i);
list.add(emp);
}
return list;
}
//輸出學(xué)院員工的信息
public void printEmployee() {
//獲取到學(xué)院員工
List<CollegeEmployee> list1 = getAllEmployee();
System.out.println("------------學(xué)院員工------------");
for (CollegeEmployee e : list1) {
System.out.println(e.getId());
}
}
}
//學(xué)校管理類
//分析SchoolManager 類的直接朋友類有哪些Employee柏卤、CollegeManager
//CollegeEmployee 不是直接朋友而是一個陌生類,這樣違背了迪米特法則
class SchoolManager {
//返回學(xué)醒炝剑總部的員工
public List<Employee> getAllEmployee() {
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 5; i++) { //這里我們增加了5 個員工到list
Employee emp = new Employee();
emp.setId("學(xué)忻凭桑總部員工id= " + i);
list.add(emp);
}
return list;
}
//該方法完成輸出學(xué)校總部和學(xué)院員工信息(id)
void printAllEmployee(CollegeManager sub) {
//分析問題
//1. 將輸出學(xué)院的員工方法钧唐,封裝到CollegeManager
sub.printEmployee();
//獲取到學(xué)忻ψ疲總部員工
List<Employee> list2 = this.getAllEmployee();
System.out.println("------------學(xué)校總部員工------------");
for (Employee e : list2) {
System.out.println(e.getId());
}
}
}
- 注意事項
- 迪米特法則的核心是降低類之間的耦合
- 但是注意:由于每個類都減少了不必要的依賴钝侠,因此迪米特法則只是要求降低類間(對象間)耦合關(guān)系该园, 并不是
要求完全沒有依賴關(guān)系
合成復(fù)用原則
在這里插入圖片描述
合成復(fù)用原則設(shè)計的核心思想:
- 找出應(yīng)用中可能需要變化之處,把它們獨立出來帅韧,不要和那些不需要變化的代碼混在一起里初。
- 針對接口編程,而不是針對實現(xiàn)編程忽舟。
- 為了交互對象之間的 松耦合設(shè)計而努力