嘻哈說:設計模式之迪米特法則

番茄課堂_懶人發表於2018-08-30

1、疑惑

在我們剛開始學習程式設計的時候,通常會將所有的方法都宣告為public,例如:

package com.fanqiekt.principle.lod;

/**
 * 廚師
 *
 * @author 番茄課堂-懶人
 */
public class Chef{
    public String flavour = "祕製調料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("放入調料:" + flavour);
        System.out.println("先炒雞蛋");
        System.out.println("再炒蕃茄");
        System.out.println("...");
    }

    /**
     * 炒酸辣土豆絲
     */
    public void cookingPotato() {
        System.out.println("放入調料:" + 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、定義

我們先來看一下迪米特法則的定義。

又稱為最少知識原則

一個軟體實體應當儘可能少地與其他實體發生相互作用。

這個比較好理解,一個類儘可能少的與其他的類產生關聯,低耦合,高內聚嘛。

迪米特法則包含兩種角色:依賴者與被依賴者。

3、含義

我們回到疑惑中的問題,Chef類好不好?

首先,Chef類的角色是被依賴者。

它暴露了flavour屬性,這是存在問題的,有哪個廚師願意把自己的獨家配方公開出去啊。

而且它還暴露了依賴者並不關心cookingTomato、cookingPotato兩個方法。

對於依賴者來說,我只需要呼叫cooking方法就可以了,至於菜具體怎麼做,就與我無關了。

並且暴露的話,程式設計師也容易懵逼,這兩個方法是幹嘛的?我要不要研究下?

所以,

從被依賴者的角度來說:只暴露應該暴露的方法或者屬性。

有個簡單的套路:

可以用private就絕不用protected,可以用protected就絕不用public

那Client類總沒什麼問題了吧。

確實,乍一看感覺沒有任何問題的,再乍乍一看還是感覺沒有問題。。。

它的不合適不是從語法呼叫方面看的,而是從依賴關係。

客人是不可以直接依賴廚師的,而應該依賴服務員。

在實際專案中,很可能會存在客人類依賴了廚師類、服務員類,而服務員類又依賴了廚師類。

這會讓程式碼非常混亂,也違背了迪米特法則。

所以,

從依賴者的角度來說:只依賴應該依賴的物件。

4、程式碼

我們按照迪米特法則優化下程式碼。

package com.fanqiekt.principle.lod;

/**
 * 廚師
 *
 * @author 番茄課堂-懶人
 */
public class Chef{
    private String flavour = "祕製調料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("放入調料:" + flavour);
        System.out.println("先炒雞蛋");
        System.out.println("再炒蕃茄");
        System.out.println("...");
    }

    /**
     * 炒酸辣土豆絲
     */
    private void cookingPotato() {
        System.out.println("放入調料:" + flavour);
        System.out.println("先放蔥薑蒜");
        System.out.println("再放土豆絲");
        System.out.println("...");
    }
}
複製程式碼

flavour宣告為private,其他類就不可訪問了,避免洩漏祕製調料。

cookingTomato、cookingPotato宣告為private

cooking需要依賴者呼叫,所以依舊為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類。。

客人點餐:蕃茄炒雞蛋
開始烹飪:蕃茄炒雞蛋
放入調料:祕製調料XXX
先炒雞蛋
再炒蕃茄
...
蕃茄炒雞蛋出鍋
蕃茄炒雞蛋上桌啦,請您品嚐!
-------
客人點餐:酸辣土豆絲
開始烹飪:酸辣土豆絲
放入調料:祕製調料XXX
先放蔥薑蒜
再放土豆絲
...
酸辣土豆絲出鍋
酸辣土豆絲上桌啦,請您品嚐!
複製程式碼

執行結果。

5、優點

降低風險

避免不該暴露的方法或者屬性暴露,從而規避風險。

避免依賴關係過於混亂。

6、嘻哈說

接下來,請您欣賞迪米特法則的原創歌曲

嘻哈說:迪米特法則
作曲:懶人
作詞:懶人
Rapper:懶人

哥們是個大廚
身材有些發福
您可以讓我做飯甚至是打滷
但您無權知曉我具體是油煎炸煮
這是我的祕密才能把客人抓住
這就是最小知識原則的迪米特法則
一個實體盡少與其他產生瓜葛
依賴者只依賴應該依賴的物件絕對可以減少bug
被依賴者只暴露該暴露的屬性還有方法呢
把風險被降低絕對不可能是假的
複製程式碼

試聽請點選這裡

閒來無事聽聽曲,知識已填腦中去;

學習複習新方式,頭戴耳機不小覷。

番茄課堂,學習也要酷。

相關文章