2016-12-28 迪米特法則+依賴倒轉原則+里氏替換原則


依賴倒轉原則

    依賴倒轉原則,也翻譯成依賴倒置原則,抽象不應該依賴細節,細節應該依賴於抽象,要針對接口編程,而不是對實現編程。如電腦中無論主板、CPU、內存、硬盤都是針對接口設計的,PC電腦硬件的發展,和麪向對象思想發展是完全類似的。

    依賴倒轉原則(爲什麼稱爲倒轉呢,因爲傳統的設計中底層提供接口,高層根據底層的接口實現功能)

        A.高層模塊不應該依賴底層模塊,兩個都應該依賴抽象。

        B.抽象不應該依賴細節,細節應該依賴抽象。

    若高層與底層都根據依賴倒轉原則來編程,則可以提高代碼複用能力,底層的更改不會對高層產生影響。


里氏代換原則

    里氏代換原則:一個軟件實體如果使用的是一個父類的對象的話,那麼一定適用於其子類的對象,而且他察覺不出父類對象和子類對象的區別。也就是說,在軟件裏面,把父類都替換成她的子類,程序的功能不受影響。

    里氏代換原則(LSP):子類必須能夠替換掉他們的父類型。

    正是由於有了這個原則,使得繼承複用成爲可能,只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才能真正被複用,而子類也能夠在父類的基礎上增加新的行爲。

    正是由於可替代性才使得使用父類類型的模塊在無需修改的情況下就可以擴展。


迪米特法則/最少知識原則

talk only to your immediate friends

    迪米特法則也叫最少知識原則,如果兩個類不必彼此直接通信,那麼這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。

    迪米特法則首先強調的是在類的結構設計上,每一個類都應當儘量降低成員的訪問權限,迪米特法則其根本思想,是強調了類之間的鬆耦合。類之間的耦合越弱,越有利於複用,一個處在弱耦合的類被修改,不會對有關係的類造成波及。

    對於OOD來說,又被解釋爲下面幾種方式:一個軟件實體應當儘可能少的與其他實體發生相互作用。每一個軟件單位對其他的單位都只有最少的知識,而且侷限於那些與本單位密切相關的軟件單位。


    迪米特法則的初衷在於降低類之間的耦合。由於每個類儘量減少對其他類的依賴,因此,很容易使得系統的功能模塊功能獨立,相互之間不存在(或很少有)依賴關係。

    迪米特法則不希望類之間建立直接的聯繫。如果真的有需要建立聯繫,也希望能通過它的友元類來轉達。因此,應用迪米特法則有可能造成的一個後果就是:系統中存在大量的中介類,這些類之所以存在完全是爲了傳遞類之間的相互調用關係——這在一定程度上增加了系統的複雜度。

    有興趣可以研究一下設計模式的門面模式Facade)等,都是迪米特法則應用的例子。這一法則卻不僅僅侷限於計算機領域,在其他領域也同樣適用。比如,美國人就在航天系統的設計中採用這一法則。


    狹義的迪米特法則

        如果兩個類不必彼此直接通信,那麼這兩個類就不應當發生直接的相互作用。如果其中的一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。

        朋友圈的確定,“朋友”條件:

            1)當前對象本身(this)

            2)以參量形式傳入到當前對象方法中的對象

            3)當前對象的實例變量直接引用的對象

            4)當前對象的實例變量如果是一個聚集,那麼聚集中的元素也都是朋友

            5)當前對象所創建的對象

        任何一個對象,如果滿足上面的條件之一,就是當前對象的“朋友”;否則就是“陌生人”。

    狹義的迪米特法則的缺點:

        在系統裏造出大量的小方法,這些方法僅僅是傳遞間接的調用,與系統的商務邏輯無關。

        遵循類之間的迪米特法則會是一個系統的局部設計簡化,因爲每一個局部都不會和遠距離的對象有直接的關聯。但是,這也會造成系統的不同模塊之間的通信效率降低,也會使系統的不同模塊之間不容易協調。


    廣義的迪米特法則在類的設計上的體現:

        優先考慮將一個類設置成不變類。

        儘量降低一個類的訪問權限。

        謹慎使用Serializable。

        儘量降低成員的訪問權限。



迪米特法則

Law of DemeterLoD

最少知識原則

Least Knowledge PrincipleLKP

    一個對象應該對其他對象有最少的瞭解。通俗地講,一個類應該對自己需要耦合或調用的類知道得最少,你(被耦合或調用的類)的內部是如何複雜都和我沒關係,那是你的事情,我就知道你提供的public方法,我就調用這麼多,其他的一概不關心。

            只和朋友交流

            朋友間也是有距離的

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

    注意:迪米特法則要求類“羞澀”一點,儘量不要對外公佈太多的public方法和非靜態的public變量,儘量內斂,多使用private、package-private、protected等訪問權限。

            是自己的就是自己的

    如果一個方法放在本類中,既不增加類間關係,也對本類不產生負面影響,就放置在本類中。


最少知識原則、迪米特法則、Least Knowledge

    要減少對象之間的交互,只留下幾個“密友”,只和你的密友談話。

    當你設計一個系統,不管是任何對象,都要注意他所交互的類有哪些,並注意他和這些類是如何交互的。這個原則希望我們在設計中,不要讓太多的類耦合在一起,免得修改系統中一部分,會影響到其他部分。

    究竟怎樣才能避免這樣呢,就任何對象而言,在該對象的方法那,我們只應該調用屬於以下範圍的方法。

        該對象本身的方法

        被當作方法的參數而傳遞進來的對象的方法

        此方法所創建或實例化的任何對象的方法

        對象的任何組件(HAS-A關係)的方法

    注意此原則告訴我們,如果某對象是調用其他的方法返回的結果,則不應調用該對象的方法,這樣就要求瞭解此類對象,則本對象會與此對象發生耦合。


public class Car {

    Engine engine; // 這是類的一個組件,我們能夠調用他的方法。

    // 其他實例變量......

    public Car() {

        // 初始化發動機

    }

    public void start(Key key) {

        Doors doors = new Doors(); // 在這裏創建了一個新的對象,他的方法可以被調用

        boolean authorized = key.turns(); // key是作爲參數傳進來的對象,其方法可以被調用

        if(authorized) {

            engine.start(); // 可以調用對象組件的方法。

            updateDashboardDisplay(); // 可以調用一個對象內的本地方法(local method)

            doors.lock(); // 可以調用你所創建或實例化的對象的方法

        }

    }

    public void updateDashboardDisplay() {

        // 更新顯示

    }

}


    最少知識原則也叫做迪米特法則,或則墨忒[tēi]耳法則(Law of Demeter)。很多人更傾向於使用原則來稱呼他,法則的感覺太強,任何原則都應該是在有幫助的時候才遵守。所有的設計都不免需要折中。雖然原則提供了方針,但是在採用原則之前,必須全盤考慮所有的因素。

    此原則雖然減少了對象之間的依賴,研究顯示會減少軟件的維護成本;但採用這個原則也會導致更到的“包裝”類被製造出來,以處理和其他組件的溝通,這可能導致複雜度和開發時間的增加,並降低運行似的性能。

    總結:

        當需要使用一個現有的類而其接口不符合你的需要時,就使用適配器。

        適配器改變接口以符合用戶的期望。

        實現適配器可能需要一番功夫,也可能不費工夫,視目標接口的大小與複雜度而定。

        適配器模式有兩種形式:對象適配器和類適配器。類適配器需要用到多重繼承。


        當需要簡化並統一一個很大的接口或者一羣複雜的接口時,使用外觀。

        外觀將客戶從一個複雜的子系統中解耦,

        實現一個外觀,需要將子系統組合進外觀中,然後將工作委託給子系統執行。

        你可以爲一個子系統實現一個以上的外觀。


    適配器將一個對象包裝起來以改變其接口;裝飾者將一個對象包裝起來以增加新的行爲和責任;而外觀將一羣對象“包裝”起來以簡化其接口。

發佈了180 篇原創文章 · 獲贊 13 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章