設計模式的七大原則(6) --迪米特法則


前言

迪米特法則,聽名字有點奇怪,但是這個法則真的非常非常有意思,在我看來,這個法則其實描述的就是一個矜持的小姑娘,害羞的惹人憐愛。但是啊,姑娘雖好,切不可"貪杯"哦~

基本介紹

  1. 一個對象應該對其他對象保持最少的了解。
  2. 類與類關系越密切,耦合度越大
  3. 一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多么復雜,都盡量將邏輯封裝在類的內部。對外除了提供的public 方法,不對外泄露任何信息
  4. 迪米特法則還有個更簡單的定義:只與直接(熟悉)的朋友通信
  5. 直接(熟悉)的朋友:每個對象都會與其他對象有耦合關系,只要兩個對象之間有耦合關系, 我們就說這兩個對象之間是朋友關系。耦合的方式很多,依賴,關聯,組合,聚合等。
    其中,我們稱出現成員變量,方法參數,方法返回值中的類為直接的朋友,而出現在局部變量中的類不是直接的朋友。也就是說,陌生的類最好不要以局部變量 的形式出現在類的內部。

把上面的概念一一翻譯成人話就是:

  1. 我們這個類姑娘啊,因為太矜持了不善於社交,所以對其他類伙伴們不怎么熟悉。
  2. 類姑娘實在是太害羞了,一旦與別人多說幾句話就會緊張的不知所措,頻頻犯錯。
  3. 矜持的類姑娘盡管心思很活躍,愛多想。但是給別人的感覺都是純潔的像一張白紙。
  4. 因為類姑娘太過於矜持,害怕陌生人,認為陌生人都是壞人,所以只與自己熟悉的朋友交流。
  5. 類姑娘熟悉的朋友有:成員變量,方法參數,方法返回值的對象。而出現在其他地方的類都是陌生人,壞人!本姑娘拒絕與你交流!!!

哈哈,這樣應該大家都能理解了。總而言之就一句話:一個類應該盡量不要知道其他類太多的東西,不要和陌生的類有太多接觸

案例

//總公司員工
class Employee{
	private String id;
	public void setId(String id){
		this.id = id;
	}
	public String getId(){
		return id;
	}
}
 
//分公司員工
class SubEmployee{
	private String id;
	public void setId(String id){
		this.id = id;
	}
	public String getId(){
		return id;
	}
}
 
class SubCompanyManager{
	public List<SubEmployee> getAllEmployee(){
		List<SubEmployee> list = new ArrayList<SubEmployee>();
		for(int i=0; i<100; i++){
			SubEmployee emp = new SubEmployee();
			//為分公司人員按順序分配一個ID
			emp.setId("分公司"+i);
			list.add(emp);
		}
		return list;
	}
}
 
class CompanyManager{
 
	public List<Employee> getAllEmployee(){
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0; i<30; i++){
			Employee emp = new Employee();
			//為總公司人員按順序分配一個ID
			emp.setId("總公司"+i);
			list.add(emp);
		}
		return list;
	}
	
	public void printAllEmployee(SubCompanyManager sub){
		List<SubEmployee> list1 = sub.getAllEmployee();
		for(SubEmployee e:list1){
			System.out.println(e.getId());
		}
 
		List<Employee> list2 = this.getAllEmployee();
		for(Employee e:list2){
			System.out.println(e.getId());
		}
	}
}
 
public class Client{
	public static void main(String[] args){
		CompanyManager e = new CompanyManager();
		e.printAllEmployee(new SubCompanyManager());
	}
}

現在這個設計的主要問題出在CompanyManager中,根據迪米特法則,只與直接的朋友發生通信,而SubEmployee類並不是CompanyManager類的直接朋友(以局部變量出現的耦合不屬於直接朋友),從邏輯上講總公司只與他的分公司耦合就行了,與分公司的員工並沒有任何聯系,這樣設計顯然是增加了不必要的耦合。按照迪米特法則,應該避免類中出現這樣非直接朋友關系的耦合。修改后的代碼如下:

class SubCompanyManager{
	public List<SubEmployee> getAllEmployee(){
		List<SubEmployee> list = new ArrayList<SubEmployee>();
		for(int i=0; i<100; i++){
			SubEmployee emp = new SubEmployee();
			//為分公司人員按順序分配一個ID
			emp.setId("分公司"+i);
			list.add(emp);
		}
		return list;
	}
	public void printEmployee(){
		List<SubEmployee> list = this.getAllEmployee();
		for(SubEmployee e:list){
			System.out.println(e.getId());
		}
	}
}
 
class CompanyManager{
	public List<Employee> getAllEmployee(){
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0; i<30; i++){
			Employee emp = new Employee();
			//為總公司人員按順序分配一個ID
			emp.setId("總公司"+i);
			list.add(emp);
		}
		return list;
	}
	
	public void printAllEmployee(SubCompanyManager sub){
		sub.printEmployee();
		List<Employee> list2 = this.getAllEmployee();
		for(Employee e:list2){
			System.out.println(e.getId());
		}
	}
}

修改后,為分公司增加了打印人員ID的方法,總公司直接調用來打印,從而避免了與分公司的員工發生耦合。

總結

雖然說矜持害羞的姑娘惹人憐愛,但是我相信在座的各位碼狼們一定會特別的苦惱,因為很多簡單的事卻變得不那么簡單直接。在你發起進攻的時候往往會給你當頭一棒。

所以啊,如果我們要遵循迪米特法則,也要根據我們的業務場景合理設計,反復權衡,既做到結構清晰,又要高內聚低耦合。不要過分的迷戀這個矜持的小姑娘,否則簡單直接的事也會變得非常的麻煩。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM