天天看點

設計模式-七大原則-迪米特法則迪米特法則

迪米特法則

DemeterPrinciple
           

目錄

  • 迪米特法則
    • 基本介紹
    • 案例1
    • 運作結果
    • 應用執行個體改進
    • 運作結果
    • 注意事項和細節

基本介紹

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

案例1

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

//用戶端
public class DemeterPrinciple{
	public static void main(String args[]){
		//建立了一個SchoolManager對象
		SchoolManager schoolmanager = new SchoolManager();
		//輸出學院員工ID和學校總部的員工資訊
		schoolmanager.printAllEmployee(new CollegeManager());
	}
}

//學校總部員工類
class Employee{
	private String id;
	public String getId(){
		return id;
	}
	public void setId(String id){
		this.id=id;
	}
}
//學院員工類
class CollegeEmployee{
	private String id;
	public String getId(){
		return id;
	}
	public void setId(String id){
		this.id=id;
	}
}
//管理學院員工的管理類
class CollegeManager{
	//傳回學院的所有員工ID
	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("學院ID="+i);
		list.add(emp);
	}
	return list;
	}
}
//分析SchoolManager類的直接朋友類有哪些?Employee、CollegeManager
//CollegeEmployee不是直接朋友而是一個陌生類,這樣違背了迪米特法則

//學校管理類
class SchoolManager{
	//傳回學校總部員工
	public List<Employee> getAllEmployee(){
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0;i<5;i++){
			Employee emp = new Employee();
			emp.setId("學校總部員工ID="+i);
			list.add(emp);
		}
	return list;
}
//該方法完成輸出學校總部和學院員工資訊(ID)
void printAllEmployee(CollegeManager sub){
	//分析問題
	//1.這裡的CollegeEmployee不是SchoolManager的直接朋友
	//2.CollegeEmployee是以局部變量方式出現在SchoolManager
	//3.違反了迪米特法則
	//擷取到學院員工
	List<CollegeEmployee> list1 = sub.getAllEmployee();
	System.out.println("----------學院員工----------");
	for(CollegeEmploye ee : list1){
	 	System.out.println(e.getId());
	}
	//擷取到學校總部員工
	List<Employee> list2=this.getAllEmployee();
	System.out.println("--------學校總部員工--------");
	for(Employe ee : list2){
		System.out.println(e.getId());
	}
	}
}
           

運作結果

----------學校員工----------
學院ID=0
學院ID=1
學院ID=2
學院ID=3
學院ID=4
學院ID=5
學院ID=6
學院ID=7
學院ID=8
學院ID=9
--------學校總部員工--------
學校總部員工ID=0
學校總部員工ID=1
學校總部員工ID=2
學校總部員工ID=3
學校總部員工ID=4
           

應用執行個體改進

1)前面設計的問題在于schoolManager中,CollegeEmployee類并不是SchoolManager類的直接朋友(分析)
2)按照迪米特法則,應該避免類中出現這樣非直接朋友關系的耦合
3)對代碼按照迪米特法則進行改進
           
//用戶端
public class DemeterPrinciple2{
	public static void main(String args[]){
		//建立了一個SchoolManager對象
		SchoolManager schoolmanager = new SchoolManager();
		//輸出學院員工ID和學校總部的員工資訊
		schoolmanager.printAllEmployee(new CollegeManager());
	}
}

//學校總部員工類
class Employee{
	private String id;
	public String getId(){
		return id;
	}
	public void setId(String id){
		this.id=id;
	}
}

//學院員工類
class CollegeEmployee{
	private String id;
	public String getId(){
		return id;
	}
	public void setId(String id){
		this.id=id;
	}
}

//管理學院員工的管理類
class CollegeManager{
	//傳回學院的所有員工ID
	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("學院ID="+i);
			list.add(emp);
		}
		return list;
	}
	//輸出學院員工資訊
	publicvoidprintEmployee(){
		//擷取到學院員工
		List<CollegeEmployee> list = getAllEmployee();
		System.out.println("----------學院員工----------");
		for(CollegeEmploye ee : list){
			System.out.println(e.getId());
		}
	}
}
//學校管理類
class SchoolManager{
	//傳回學校總部員工
	public List<Employee> getAllEmployee(){
		List<Employee> list = new ArrayList<Employee>();
		for(int i=0;i<5;i++){
			Employee emp = new Employee();
			emp.setId("學校總部員工ID="+i);
			list.add(emp);
		}
		return list;
	}
	//該方法完成輸出學校總部和學院員工資訊(ID)
	void printAllEmployee(CollegeManagersub){
		//分析問題
		//1.将輸出學院的員工方法,封裝到CollegeManager
		sub.printEmployee();
		//擷取學校總部員工
		List<Employee> list2 = this.getAllEmployee();
		System.out.println("--------學校總部員工--------");
		for(Employe ee:list2){
			System.out.println(e.getId());
		}
	}
}
           

運作結果

----------學院員工----------
學院ID=0
學院ID=1
學院ID=2
學院ID=3
學院ID=4
學院ID=5
學院ID=6
學院ID=7
學院ID=8
學院ID=9
--------學校總部員工--------
學校總部員工ID=0
學校總部員工ID=1
學校總部員工ID=2
學校總部員工ID=3
學校總部員工ID=4
           

注意事項和細節

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