?? The Law of Demeter和 Principle of Least Knowledge講的都是一回事,是說一個(gè)軟件實(shí)體要盡可能的只與和它最近的實(shí)體進(jìn)行通訊。通常被表述為:
talk only to your
immediate friends ( 只和離你最近的朋友進(jìn)行交互)。?
??
“talk”,其實(shí)就是對(duì)象間方法的調(diào)用。這條規(guī)則表明了對(duì)象間方法調(diào)用的原則:
(1)?????? 調(diào)用對(duì)象本身的方法;
(2)?????? 調(diào)用通過參數(shù)傳入的對(duì)象的方法;
(3)?????? 在方法中創(chuàng)建的對(duì)象的方法;
(4)?????? 所包含對(duì)象的方法。
上面的4點(diǎn)看起來有點(diǎn)別扭,下面通過一個(gè)具體的例子,就可以對(duì)上述4條guideline有進(jìn)一步感性的認(rèn)識(shí):
?1?public?class?Car?{
?2???Engine?engine;
?3???
?4???public?Car()?{
?5?????//initialize?engine,etc.
?6?}
?7?
?8?public?void?start(Key?key)?{
?9???Doors?doors?=?new?Doors();
10???boolean?authorized?=?key.turns();
11???
12???if(authorized)?{
13?????engine.start();
14?????updateDashboardDisplay();
15?????doors.lock();
16?}
17?
18?public?void?updateDashboardDisplay()?{
19???//update?display
20}
21
22?}
下面對(duì)start()方法中的語(yǔ)句進(jìn)行分析:
第10行-key.turns():符合上述的第(2)條,key對(duì)象是通過參數(shù)傳入start()方法的。
第13行-engine.start():符合上述的第(4)條,engine對(duì)象是包含在Car的對(duì)象之中的。
第14行-UpdateDashboardDisplay():符合上述的第(1)條,UpdateDashboardDisplay()方法是Car對(duì)像自身的方法。
第15行-doors.lock():符合上述的第(3)條,doors對(duì)象是在start()方法中創(chuàng)建的對(duì)象。
接下來看一個(gè)違反Principle of Least Knowledge的例子:
1?public?float?getTemp()?{
2???Thermometer?thermometer?=?station.getThermometer();
3???return?thermometer.getTemperature();
4?}
上面的方法中station對(duì)象是immediate friends。但是上面的代碼卻從station對(duì)象中返回了一個(gè)Thermometer對(duì)象,然后調(diào)用了thermometer對(duì)象的getTemperature()方法,違反了Principle
of Least Knowledge。
下面對(duì)上面的方法作出符合Principle of Least Knowledge的改進(jìn):
1?public?float?getTemp()?{
2???return?station.?getTemperature();
3?}
我們?cè)?/span>Station類中添加一個(gè)方法getTemperature()。這個(gè)方法將調(diào)用Station類中含有的Thermometer對(duì)象的getTemperature()。這樣getTemp()方法就只知道Station對(duì)象而不知道Thermometer對(duì)象。
總結(jié):笛米特法則告訴我們要盡量只和離自己最近的對(duì)象進(jìn)行交互。離自己最近的對(duì)象包括:自身包含的對(duì)象,方法中創(chuàng)建的對(duì)象,通過參數(shù)傳進(jìn)的對(duì)象,還有自己本身。
?