迪米特原则英文名称为 Law of Demeter , 缩写是 LOD,也称最少知识原则(Least Knowledge Principle),它的原则是: 一个对象应该对其他对象有最少的了解。
也就是说,一个类应该对自己需要耦合或者调用的类知道的最少,不需要知道类内部如何实现与调用,调用者与依赖者只需要知道它需要的方法即可,其他一概不管。
下面通过租房的案例进行解析 迪米特原则。
在北上广的朋友们都知道,租房时,绝大多数都会通过中介进行找房,我们设定的情况是:租客只给出房间的面积和租金,其他一概不管,中介将符合我们要求的房子推荐给我就可以了,下面给用代码来演示一下:
/*
* 房间
* */
public class Room {
public float area;
public float price;
public Room(float area, float price) {
this.area = area;
this.price = price;
}
@Override
public String toString() {
return "Room{" +
"area=" + area +
", price=" + price +
'}';
}
}
/*
* 中介
* */
public class Mediator {
List<Room> roomList = new ArrayList<Room>();
public Mediator() {
for (int i = 0; i < 5; i++){
roomList.add(new Room(14+i,(14+i)*130));
}
}
public List<Room> getRoomList(){
return roomList;
}
}
/*
* 租客
*
* */
public class Tenant {
public float roomArea;
public float roomPrice;
public static final float diffPrice = 100.0001f;
public static final float diffArea = 0.00001f;
public void rentRoom(Mediator mediator){
List<Room> roomList = mediator.getRoomList();
for (Room room : roomList){
if (isSuitable(room)){
System.out.println("租到房间了!" + room);
break;
}
}
}
private boolean isSuitable(Room room){
return Math.abs(room.price - roomPrice) < diffPrice
&& Math.abs(room.area - roomArea) < diffArea;
}
}
上面的代码中,Tenant 不仅依赖 Mediator 类 ,还和 Room 类进行频繁的交互,租客类要求是通过中介找到一间合适自己的房间,如果把这些检测条件都放在了 Tenant 类中,则会削弱中介的功能,而且导致 Tenant 类和 Room 类的耦合性较高。上面的代码结构如下图所示。
既然耦合性太高了,那么我们呢就需要进行解耦,上面的代码进行重构,将检测的条件放在Mediator 类中,重构代码如下所示:
/*
* 中介
* */
public class Mediator {
List<Room> roomList = new ArrayList<Room>();
public Mediator() {
for (int i = 0; i < 5; i++){
roomList.add(new Room(14+i,(14+i)*130));
}
}
public Room rentOut(float area,float price){
for (Room room : roomList){
if(isSuitable(area,price,room)){
return room;
}
}
return null;
}
private boolean isSuitable(float area,float price,Room room){
return Math.abs(room.price - price) < Tenant.diffPrice
&& Math.abs(room.area - area) < Tenant.diffArea;
}
}
/*
* 租客
*
* */
public class Tenant {
public float roomArea;
public float roomPrice;
public static final float diffPrice = 100.0001f;
public static final float diffArea = 0.00001f;
public void rentRoom(Mediator mediator){
System.out.println("租到房啦!"+ mediator.rentOut(roomArea,roomPrice));
}
}
重构后的结构图如下图所示:
将对 Room 的判定操作移到 Mediator 类中,这本是中介的职责,根据租客的条件查找符合要求的房子,然后将结果交给租客就可以了,租客不需要知道太多关于Room的细节。