1、疑惑
在我們剛開始學習編程的時候影兽,通常會將所有的方法都聲明為public揭斧,例如:
package com.fanqiekt.principle.lod;
/**
* 廚師
*
* @author 番茄課堂-懶人
*/
public class Chef{
public String flavour = "秘制調(diào)料XXX";
/**
* 做飯
* @param dishName 下單的菜名
*/
public void cooking(String dishName) {
System.out.println("開始烹飪:"+dishName);
switch (dishName){
case "西紅柿炒雞蛋":
cookingTomato();
break;
case "酸辣土豆絲":
cookingPotato();
break;
}
System.out.println(dishName + "出鍋");
}
/**
* 炒西紅柿雞蛋
*/
public void cookingTomato() {
System.out.println("放入調(diào)料:" + flavour);
System.out.println("先炒雞蛋");
System.out.println("再炒西紅柿");
System.out.println("...");
}
/**
* 炒酸辣土豆絲
*/
public void cookingPotato() {
System.out.println("放入調(diào)料:" + flavour);
System.out.println("先放蔥姜蒜");
System.out.println("再放土豆絲");
System.out.println("...");
}
}
廚師類。
package com.fanqiekt.principle.lod;
/**
* 客人
* @Author: 番茄課堂-懶人
*/
public class Client {
public static void main(String[] args){
Chef chef = new Chef();
chef.cooking("西紅柿炒雞蛋");
System.out.println("-------");
chef.cooking("酸辣土豆絲");
}
}
客人類峻堰。
這樣做好不好讹开?
大家可以先思考下。
2捐名、定義
我們先來看一下迪米特法則的定義旦万。
又稱為最少知識原則。
一個軟件實體應當盡可能少地與其他實體發(fā)生相互作用镶蹋。
這個比較好理解成艘,一個類盡可能少的與其他的類產(chǎn)生關聯(lián),低耦合贺归,高內(nèi)聚嘛淆两。
迪米特法則包含兩種角色:依賴者與被依賴者。
3拂酣、含義
我們回到疑惑中的問題秋冰,Chef類好不好?
首先踱葛,Chef類的角色是被依賴者丹莲。
它暴露了flavour屬性,這是存在問題的尸诽,有哪個廚師愿意把自己的獨家配方公開出去啊。
而且它還暴露了依賴者并不關心cookingTomato盯另、cookingPotato兩個方法性含。
對于依賴者來說,我只需要調(diào)用cooking方法就可以了鸳惯,至于菜具體怎么做商蕴,就與我無關了叠萍。
并且暴露的話,程序員也容易懵逼绪商,這兩個方法是干嘛的苛谷?我要不要研究下?
所以格郁,
從被依賴者的角度來說:只暴露應該暴露的方法或者屬性腹殿。
有個簡單的套路:
可以用private就絕不用protected,可以用protected就絕不用public例书。
那Client類總沒什么問題了吧锣尉。
確實,乍一看感覺沒有任何問題的决采,再乍乍一看還是感覺沒有問題自沧。。树瞭。
它的不合適不是從語法調(diào)用方面看的拇厢,而是從依賴關系。
客人是不可以直接依賴廚師的晒喷,而應該依賴服務員旺嬉。
在實際項目中,很可能會存在客人類依賴了廚師類厨埋、服務員類邪媳,而服務員類又依賴了廚師類。
這會讓代碼非车聪荩混亂雨效,也違背了迪米特法則。
所以废赞,
從依賴者的角度來說:只依賴應該依賴的對象徽龟。
4、代碼
我們按照迪米特法則優(yōu)化下代碼唉地。
package com.fanqiekt.principle.lod;
/**
* 廚師
*
* @author 番茄課堂-懶人
*/
public class Chef{
private String flavour = "秘制調(diào)料XXX";
/**
* 做飯
* @param dishName 下單的菜名
*/
public void cooking(String dishName) {
System.out.println("開始烹飪:"+dishName);
switch (dishName){
case "西紅柿炒雞蛋":
cookingTomato();
break;
case "酸辣土豆絲":
cookingPotato();
break;
}
System.out.println(dishName + "出鍋");
}
/**
* 炒西紅柿雞蛋
*/
private void cookingTomato() {
System.out.println("放入調(diào)料:" + flavour);
System.out.println("先炒雞蛋");
System.out.println("再炒西紅柿");
System.out.println("...");
}
/**
* 炒酸辣土豆絲
*/
private void cookingPotato() {
System.out.println("放入調(diào)料:" + flavour);
System.out.println("先放蔥姜蒜");
System.out.println("再放土豆絲");
System.out.println("...");
}
}
flavour聲明為private据悔,其他類就不可訪問了,避免泄漏秘制調(diào)料耘沼。
cookingTomato极颓、cookingPotato聲明為private
cooking需要依賴者調(diào)用,所以依舊為public群嗤。
package com.fanqiekt.principle.lod;
/**
* 服務員
*
* @author 番茄課堂-懶人
*/
public class Waiter {
private Chef chef = new Chef();
/**
* 點餐
* @param dishName 餐名
*/
public void order(String dishName) {
System.out.println("客人點餐:"+dishName);
chef.cooking(dishName);
System.out.println(dishName+"上桌啦菠隆,請您品嘗!");
}
}
服務員類,依賴了Chef對象骇径,并聲明為private躯肌。
package com.fanqiekt.principle.lod;
/**
* 客人
* @Author: 番茄課堂-懶人
*/
public class Client {
public static void main(String[] args){
Waiter waiter = new Waiter();
waiter.order("西紅柿炒雞蛋");
System.out.println("-------");
waiter.order("酸辣土豆絲");
}
}
客人類,依賴了Waiter類破衔。清女。
客人點餐:西紅柿炒雞蛋
開始烹飪:西紅柿炒雞蛋
放入調(diào)料:秘制調(diào)料XXX
先炒雞蛋
再炒西紅柿
...
西紅柿炒雞蛋出鍋
西紅柿炒雞蛋上桌啦,請您品嘗晰筛!
-------
客人點餐:酸辣土豆絲
開始烹飪:酸辣土豆絲
放入調(diào)料:秘制調(diào)料XXX
先放蔥姜蒜
再放土豆絲
...
酸辣土豆絲出鍋
酸辣土豆絲上桌啦嫡丙,請您品嘗!
運行結果传惠。
5迄沫、優(yōu)點
降低風險
避免不該暴露的方法或者屬性暴露,從而規(guī)避風險卦方。
避免依賴關系過于混亂羊瘩。
6、嘻哈說
接下來盼砍,請您欣賞懶人為迪米特法則創(chuàng)作的歌曲尘吗。
嘻哈說:迪米特法則
作曲:懶人
作詞:懶人
Rapper:懶人
哥們是個大廚
身材有些發(fā)福
您可以讓我做飯甚至是打鹵
但您無權知曉我具體是油煎炸煮
這是我的秘密才能把客人抓住
這就是最小知識原則的迪米特法則
一個實體盡少與其他產(chǎn)生瓜葛
依賴者只依賴應該依賴的對象絕對可以減少bug
被依賴者只暴露該暴露的屬性還有方法呢
把風險被降低絕對不可能是假的
閑來無事聽聽曲,知識已填腦中去浇坐;
學習復習新方式泼掠,頭戴耳機不小覷孕似。
番茄課堂鱼填,學習也要酷橘沥。