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

Java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則介紹

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

一、迪米特法則的定義

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

二、迪米特法則的含義

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

(一)、只和朋友交流

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

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

其實(shí)現(xiàn)過程如下代碼:

老師類:

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

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

體育委員GroupLeader的代碼如下:

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

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

public class Girl {
}

再定義一個(gè)場(chǎng)景類:

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

運(yùn)行結(jié)果如下:

女生數(shù)量: 10

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

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

問題已經(jīng)發(fā)現(xiàn),我們修改一下程序,將類圖稍作調(diào)整,如下圖所示:

修改后的老師類:

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

修改后的GroupLeader體育委員類:

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

在GroupLeader類中定義了一個(gè)構(gòu)造函數(shù),通過構(gòu)造函數(shù)傳遞了依賴關(guān)系。同時(shí),對(duì)場(chǎng)景類也進(jìn)行了一些調(diào)整:

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));
    }
}

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

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

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

我們?cè)诎惭b軟件的時(shí)候,經(jīng)常會(huì)有一個(gè)導(dǎo)向動(dòng)作,第一步是確認(rèn)是否安裝,第二步確認(rèn)Lisence,再然后選擇安裝目錄...這是一個(gè)典型的順序執(zhí)行動(dòng)作,具體到程序中就是:調(diào)用一個(gè)或多個(gè)類,先執(zhí)行第一個(gè)方法,然后是第二個(gè)方法,根據(jù)返回結(jié)果再來看是否可以調(diào)用第三個(gè)方法,或者第四個(gè)方法,等等。其類圖大體如下:

實(shí)現(xiàn)過程如下:

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

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

InstallSoftware類的代碼如下:

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

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

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

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

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

在Wizard類中增加一個(gè)installWizard方法,對(duì)安裝過程進(jìn)行封裝,同時(shí)把所有的三個(gè)public方法修改為private方法,如下:

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

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

修改后的InstallSoftware代碼如下:

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

場(chǎng)景類沒有任何改變,通過進(jìn)行重構(gòu),類間的耦合關(guān)系變?nèi)趿?,結(jié)構(gòu)也清晰了,變更引起的風(fēng)險(xiǎn)也變小了。

一個(gè)類公開的public屬性或者方法越多,修改時(shí)涉及的面就越大,變更引起的風(fēng)險(xiǎn)擴(kuò)散也就越大。因此,為了保持朋友間的距離,在設(shè)計(jì)時(shí)需要反復(fù)衡量:是否還可以再減少public屬性和方法,是否可以修改為private、package-private、protected等訪問權(quán)限,是否可以加上final關(guān)鍵字等。

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

在實(shí)際應(yīng)用中經(jīng)常會(huì)出現(xiàn)這樣一個(gè)方法:放在本類中也可以,放在其他類也沒有錯(cuò),那怎么去衡量呢?可以檢查這樣一個(gè)原則:如果一個(gè)方法放在本類中,既不增加類間關(guān)系,也對(duì)本類不產(chǎn)生負(fù)面影響,那就放置在本類中。

三、總結(jié)

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

到此這篇關(guān)于Java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則介紹的文章就介紹到這了,更多相關(guān)Java迪米特法則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis之動(dòng)態(tài)SQL使用小結(jié)(全網(wǎng)最新)

    Mybatis之動(dòng)態(tài)SQL使用小結(jié)(全網(wǎng)最新)

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

    java查詢近七日數(shù)據(jù)功能的實(shí)現(xiàn)

    這篇文章主要介紹了java查詢近七日數(shù)據(jù)功能的實(shí)現(xiàn),文章內(nèi)容詳細(xì),簡(jiǎn)單易懂,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2023-01-01
  • Java Swing null絕對(duì)布局的實(shí)現(xiàn)示例

    Java Swing null絕對(duì)布局的實(shí)現(xiàn)示例

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

    原因分析IDEA導(dǎo)入Spring-kafka項(xiàng)目Gradle編譯失敗

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

    Mybatis游標(biāo)查詢大量數(shù)據(jù)方式

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

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

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

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

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

    JAVA中JVM的重排序詳細(xì)介紹

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

    springcloud 中 zuul 修改請(qǐng)求參數(shù)信息的方法

    這篇文章主要介紹了springcloud 中 zuul 修改請(qǐng)求參數(shù)信息的方法,需要的朋友可以參考下
    2018-02-02
  • Java實(shí)現(xiàn)word文檔轉(zhuǎn)成圖片的示例詳解

    Java實(shí)現(xiàn)word文檔轉(zhuǎn)成圖片的示例詳解

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

最新評(píng)論