欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java面向對象設計原則之迪米特法則介紹

 更新時間:2023年02月14日 10:18:05   作者:每天都要進步一點點  
迪米特法則解決類與類之間耦合度問題,如果類A調用了B類的某一個方法,則這兩個類就形成了一種緊耦合的方式,當B類這個方法發(fā)生變化時,一定會影響A類的執(zhí)行結果。迪米特法則要求每一個類盡可能少的與其他類發(fā)生關系

一、迪米特法則的定義

迪米特法則,也稱為最少知識原則,雖然名字不同,但描述的是同一個規(guī)則:一個對象應該對其他對象有最少的了解。通俗地講,一個類應該對自己需要耦合或調用的類知道得最少,被耦合或調用的類的內部是如何復雜都和我沒關系,我就知道你提供的這么多public方法,我就調用這么多,其他的我一概不關心。

二、迪米特法則的含義

迪米特法則對類的低耦合提出了明確的規(guī)定,其包含以下幾層含義。

(一)、只和朋友交流

迪米特法則,要求只與直接朋友通信。什么叫直接朋友?每個對象都必然會與其他對象有耦合關系,兩個對象之間的耦合就成為朋友關系,這種關系的類型有很多,例如組合、聚合、依賴等。下面我們舉例說明如何才能做到只與直接朋友進行交流。

舉例:老師讓體育委員確認一下全班女生是否都到齊?類圖如下圖所示:

其實現過程如下代碼:

老師類:

public class Teacher {
    //老師發(fā)出命令,清點一下女生人數
    public void command(GroupLeader groupLeader) {
        List<Girl> girls = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            girls.add(new Girl());
        }
        //告訴體育委員開始執(zhí)行清查任務
        groupLeader.countGirls(girls);
    }
}

老師只有一個方法command,先定義出所有的女生,然后發(fā)布命令給體育委員,去清點女生的人數。

體育委員GroupLeader的代碼如下:

public class GroupLeader {
    public void countGirls(List<Girl> girlList) {
        System.out.println("女生數量: " + girlList.size());
    }
}

老師類和體育委員類都對Girl類產生依賴,而且女生類不需要執(zhí)行任何動作,因此定義如下:

public class Girl {
}

再定義一個場景類:

public class Client {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.command(new GroupLeader());
    }
}

運行結果如下:

女生數量: 10

體育委員按照老師的要求對女生進行了清點,并得出了數量。我們回過頭來思考一下這個程序有什么問題,首先確定Teacher類有幾個朋友類,它僅有一個朋友類-------GroupLeader,為什么Girl不是朋友類呢?Teacher對Girl類產生了依賴啊,朋友類的定義是這樣的:出現在成員變量、方法的輸入參數、輸出參數中的類成為成員朋友類。而Gril這個類是出現在command方法內部的,因此不屬于Teacher的直接朋友。

迪米特法則告訴我們一個類只與朋友類交流,但是我們剛剛定義的command方法卻與Girl類有了交流,聲明了List<Girl>動態(tài)集合,這樣就破壞了Teacher的健壯性。

問題已經發(fā)現,我們修改一下程序,將類圖稍作調整,如下圖所示:

修改后的老師類:

public class Teacher {
    //老師發(fā)出命令,清點一下女生人數
    public void command(GroupLeader groupLeader) {
        //告訴體育委員開始執(zhí)行清查任務
        groupLeader.countGirls();
    }
}

修改后的GroupLeader體育委員類:

public class GroupLeader {
    private List<Girl> girls;
    public GroupLeader(List<Girl> girls) {
        this.girls = girls;
    }
    public void countGirls() {
        System.out.println("女生數量: " + girls.size());
    }
}

在GroupLeader類中定義了一個構造函數,通過構造函數傳遞了依賴關系。同時,對場景類也進行了一些調整:

public class Client {
    public static void main(String[] args) {
        List<Girl> girls = new ArrayList<>();
        //初始化女生信息
        for (int i = 0; i < 10; i++) {
            girls.add(new Girl());
        }
        ;
        Teacher teacher = new Teacher();
        //老師發(fā)布命令
        teacher.command(new GroupLeader(girls));
    }
}

對程序進行了簡單的修改,把Teacher的List<Girl>的初始化移動到了場景類中,同時在GroupLeader中增加對Girl的注入,避開了Teacher對陌生類Girl的訪問,降低了系統(tǒng)間耦合,提高了系統(tǒng)的健壯性。

(二)、朋友間也是有距離的

人和人之間是有距離的,太遠關系逐漸疏遠,最終形同陌路;太近就相互刺傷。迪米特法則就是對這個距離進行描述,即使是朋友類之間也不能無話不說,無所不知。

我們在安裝軟件的時候,經常會有一個導向動作,第一步是確認是否安裝,第二步確認Lisence,再然后選擇安裝目錄...這是一個典型的順序執(zhí)行動作,具體到程序中就是:調用一個或多個類,先執(zhí)行第一個方法,然后是第二個方法,根據返回結果再來看是否可以調用第三個方法,或者第四個方法,等等。其類圖大體如下:

實現過程如下:

public class Wizard {
    private Random random = new Random(System.currentTimeMillis());
    /**
     * 第一步
     *
     * @return
     */
    public int first() {
        System.out.println("執(zhí)行第一個方法");
        return random.nextInt(100);
    }
    /**
     * 第二步
     *
     * @return
     */
    public int second() {
        System.out.println("執(zhí)行第二個方法");
        return random.nextInt(100);
    }
    /**
     * 第三步
     *
     * @return
     */
    public int third() {
        System.out.println("執(zhí)行第三個方法");
        return random.nextInt(100);
    }
}

在Wizard類中分別定義了三個步驟方法,每個步驟中都有相關的業(yè)務邏輯完成指定的任務,我們使用一個隨機函數來代替業(yè)務執(zhí)行的返回值。

InstallSoftware類的代碼如下:

public class InstallSoftware {
    public void install(Wizard wizard) {
        int first = wizard.first();
        //根據first的返回結果,看是否需要執(zhí)行second
        if (first > 50) {
            int second = wizard.second();
            if (second > 50) {
                int third = wizard.third();
                if (third > 50) {
                    wizard.first();
                }
            }
        }
    }
}

根據每個方法執(zhí)行的結果決定是否繼續(xù)執(zhí)行下一個方法,模擬人工的選擇操作。場景類如下:

public class Client {
    public static void main(String[] args) {
        InstallSoftware installSoftware = new InstallSoftware();
        installSoftware.install(new Wizard());
    }
}

以上程序很簡單,運行結果和隨機數有關,每次執(zhí)行的結果都不相同,需要讀者自己運行并查看結果。程序雖然簡單,但隱藏的問題可不簡單,思考一下程序有什么問題?

Wizard類把太多的方法暴露給InstallSoftware類,兩者的朋友關系太親密了,耦合關系變得異常牢固。如果要將Wizard類中的first方法返回值的類型由int修改為boolean,就需要修改InstallSoftware類,從而把修改變更的風險擴散開了。因此,這種耦合是不合適的,我們需要對設計進行重構,重構后的類圖如下:

在Wizard類中增加一個installWizard方法,對安裝過程進行封裝,同時把所有的三個public方法修改為private方法,如下:

public class Wizard {
    private Random random = new Random(System.currentTimeMillis());
    /**
     * 第一步
     *
     * @return
     */
    private int first() {
        System.out.println("執(zhí)行第一個方法");
        return random.nextInt(100);
    }
    /**
     * 第二步
     *
     * @return
     */
    private int second() {
        System.out.println("執(zhí)行第二個方法");
        return random.nextInt(100);
    }
    /**
     * 第三步
     *
     * @return
     */
    private int third() {
        System.out.println("執(zhí)行第三個方法");
        return random.nextInt(100);
    }
    public void installWizard() {
        int first = this.first();
        //根據first的返回結果,看是否需要執(zhí)行second
        if (first > 50) {
            int second = this.second();
            if (second > 50) {
                int third = this.third();
                if (third > 50) {
                    this.first();
                }
            }
        }
    }
}

講啊三個步驟的訪問權限修改為private,同時把InstallSoftware中的方法installWizard()移動到了Wizard類中。通過這樣的重構后,Wizard類就只對外公布了一個public方法,即使要修改first方法的返回值,影響的也僅僅是Wizard本身,其他類不受影響,這顯示了類的高內聚特性。

修改后的InstallSoftware代碼如下:

public class InstallSoftware {
    public void install(Wizard wizard) {
        wizard.installWizard();
    }
}

場景類沒有任何改變,通過進行重構,類間的耦合關系變弱了,結構也清晰了,變更引起的風險也變小了。

一個類公開的public屬性或者方法越多,修改時涉及的面就越大,變更引起的風險擴散也就越大。因此,為了保持朋友間的距離,在設計時需要反復衡量:是否還可以再減少public屬性和方法,是否可以修改為private、package-private、protected等訪問權限,是否可以加上final關鍵字等。

(三)、是自己的就是自己的

在實際應用中經常會出現這樣一個方法:放在本類中也可以,放在其他類也沒有錯,那怎么去衡量呢?可以檢查這樣一個原則:如果一個方法放在本類中,既不增加類間關系,也對本類不產生負面影響,那就放置在本類中。

三、總結

迪米特法則的核心觀念就是類間解耦,弱耦合,只有弱耦合了以后,類的復用率才可以提高。其要求的結果就是產生了大量的中轉或跳轉類,導致系統(tǒng)的復雜性提高,同時也為維護帶來了難度。讀者在采用迪米特法則的時候需要反復權衡,既做到讓結構清晰,又做到高內聚低耦合。

到此這篇關于Java面向對象設計原則之迪米特法則介紹的文章就介紹到這了,更多相關Java迪米特法則內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis之動態(tài)SQL使用小結(全網最新)

    Mybatis之動態(tài)SQL使用小結(全網最新)

    MyBatis令人喜歡的一大特性就是動態(tài)SQL,?在使用JDBC的過程中,?根據條件進行SQL的拼接是很麻煩且很容易出錯的,MyBatis通過OGNL來進行動態(tài)SQL的使用解決了這個麻煩,對Mybatis動態(tài)SQL相關知識感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • java查詢近七日數據功能的實現

    java查詢近七日數據功能的實現

    這篇文章主要介紹了java查詢近七日數據功能的實現,文章內容詳細,簡單易懂,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2023-01-01
  • Java Swing null絕對布局的實現示例

    Java Swing null絕對布局的實現示例

    這篇文章主要介紹了Java Swing null絕對布局的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • 原因分析IDEA導入Spring-kafka項目Gradle編譯失敗

    原因分析IDEA導入Spring-kafka項目Gradle編譯失敗

    這篇文章主要為大家介紹分析了IDEA導入Spring-kafka項目Gradle中編譯失敗原因及解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • Mybatis游標查詢大量數據方式

    Mybatis游標查詢大量數據方式

    這篇文章主要介紹了Mybatis游標查詢大量數據方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解java開發(fā)webservice的幾種方式

    詳解java開發(fā)webservice的幾種方式

    webservice的應用已經越來越廣泛了,下面介紹幾種在Java體系中開發(fā)webservice的方式,有興趣的可以了解一下。
    2016-11-11
  • 淺談JavaWeb中的web.xml配置部署描述符文件

    淺談JavaWeb中的web.xml配置部署描述符文件

    下面小編就為大家?guī)硪黄獪\談JavaWeb中的web.xml配置部署描述符文件。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • JAVA中JVM的重排序詳細介紹

    JAVA中JVM的重排序詳細介紹

    重排序通常是編譯器或運行時環(huán)境為了優(yōu)化程序性能而采取的對指令進行重新排序執(zhí)行的一種手段。重排序分為兩類:編譯期重排序和運行期重排序,分別對應編譯時和運行時環(huán)境
    2014-05-05
  • springcloud 中 zuul 修改請求參數信息的方法

    springcloud 中 zuul 修改請求參數信息的方法

    這篇文章主要介紹了springcloud 中 zuul 修改請求參數信息的方法,需要的朋友可以參考下
    2018-02-02
  • Java實現word文檔轉成圖片的示例詳解

    Java實現word文檔轉成圖片的示例詳解

    本文主要為大家詳細介紹了如何在Java項目中引用aspose-words和poi-tljar包實現word文檔轉成圖片,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-10-10

最新評論