一.簡稱
英文全稱為Law of Demeter ,縮寫是LOD,也稱最少知識原則。
二.定義
一個對象應該對其他對象有最少的了解。通俗的講,一個類應該對自己需要耦合或者調用的類知道的最少,類的內部如何實現與調用者或依賴者沒關系,調用者或者依賴者只需要知道它需要的方法即可,其他的一概不用管。
迪米特法則還有一個英文解釋是 Only talk to your immedate friends ,即只與直接的朋友通信。什么叫直接的朋友呢?每個對象都不然會與其他對象有耦合關系,兩個對象之間的耦合就成為朋友關系,這種關系的類型有很多,如組合、聚合、依賴。
三.問題
類與類之間的關系約密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。
四.解決
我們需要分清誰才是我們直接的朋友,減少與沒有直接關系的類的耦合
舉例
比如我們買房子,需要通過銷售,我們只需要告訴他我們能夠支付的價錢及住房面積,至于找房子的事就交給銷售去干,買房者不直接去找房子。
*房子
/
public class Room {
public float area;
public float price;
public Room(float area,float price){
this.area = area;
this.price = price;
}
}
/**
* 銷售
*/
public class Mediator {
List<Room> mRooms = new ArrayList<>();
public Mediator() {
for (int i = 0; i < 5; i++) {
mRooms.add(new Room(15 + i, (15 + i) * 150));
}
}
public List<Room> getAllRooms() {
return mRooms;
}
}
/**
* 買房者
*/
public class Customer {
private String TAG ="Customer";
public float roomArea;
public float roomPrice;
public static final float diffPrice =100.0001f;
public static final float diffArea =0.00001f;
public void sellRoom(Mediator mediator){
List<Room> rooms =mediator.getAllRooms();
for(Room room: rooms){
if(isFit(room)){
Log.e(TAG,"買到房啦"+room);
break;
}
}
}
private boolean isFit(Room room) {
return Math.abs(room.price - roomPrice) <diffPrice &&Math.abs(room.area - roomArea)< diffArea;
}
}
從上面的代碼看,Customer類不僅依賴了Mediator類,還需頻繁的與Room打交道,Customer類與Room的耦合度較高,因為Customer必須知道許多關于Room的細節,如果Room發生變化時,Customer也必須跟著變化。Customer與Mediator耦合度也太高。
我們要分清誰是購買者的真正的朋友,自然是銷售,所以我只知道銷售就行了,把Customer中關于Room的相關操作移除到Mediator中。
重構如下:
/**
* 銷售
*/
public class Mediator {
List<Room> mRooms = new ArrayList<>();
public Mediator() {
for (int i = 0; i < 5; i++) {
mRooms.add(new Room(15 + i, (15 + i) * 150));
}
}
public Room sellOut(float area,float price){
for(Room room: mRooms){
if(isFit(area,price,room)){
return room;
}
}
return null;
}
private boolean isFit(float area,float price,Room room) {
return Math.abs(room.price - price) < Customer.diffPrice && Math.abs(room.area - area) < Customer.diffArea;
}
}
/**
* 買房者
*/
public class Customer {
private String TAG ="Customer";
public float roomArea;
public float roomPrice;
public static final float diffPrice =100.0001f;
public static final float diffArea =0.00001f;
public void sellRoom(Mediator mediator){
Log.e(TAG,"買到房啦"+mediator.sellOut(roomArea,roomPrice));
}
}
結構圖如下
將對于Room的判定操作放到了Mediator類中,根據用戶設定的條件查找合適的房子,并將結果交給購買者就可以了。購房者不需直接與房子接觸。至于看房子那也要等到銷售找到合適的房子之后了。
只與直接的朋友通信,就能夠將我們從復雜的關系網中抽離出來,使耦合讀更低、穩定性更好。
總結
迪米特原則的優點:
(1)提高可讀性
(2)降低耦合度
(3)提高穩定性
頭條號申請者:飛奔的小付