1. 程式人生 > >面向物件六大原則----里氏替換原則,依賴倒置原則

面向物件六大原則----里氏替換原則,依賴倒置原則

單一職責原則 英文名稱是Single Responsibility Principle,簡稱SRP

開閉原則英文全稱是Open Close Principle,簡稱OCP

里氏替換原則 英文全稱是Liskov Substitution Principle,簡稱LSP

依賴倒置原則 英文全稱是Dependence Inversion Principle,簡稱DIP

介面隔離原則 英文全稱是InterfaceSegregation Principles,簡稱ISP

迪米特原則 英文全稱為Law of Demeter,簡稱LOD,也稱為最少知識原則(Least Knowledge Principle)

構建擴充套件性更好的系統——里氏替換原則

前面兩章講了單一職責原則開閉原則。里氏替換原則英文全稱是Liskov Substitution Principle,簡稱LSP。 由2008年圖靈獎得主、美國第一位電腦科學女博士Barbara Liskov教授和卡內基·梅隆大學Jeannette Wing教授於1994年提出。其嚴格表述如下:如果對每一個型別為S的物件o1,都有型別為T的物件o2,使得以T定義的所有程式P在所有的物件o1代換o2時,程式P的行為沒有變化,那麼型別S是型別T的子型別。這個定義比較拗口且難以理解,因此我們一般使用它的另一個通俗版定義::所有引用基類的地方必須能透明地使用其子類的物件。

 里氏代換原則告訴我們,在軟體中將一個基類物件替換成它的子類物件,程式將不會產生任何錯誤和異常,反過來則不成立,如果一個軟體實體使用的是一個子類物件的話,那麼它不一定能夠使用基類物件。例如:我喜歡動物,那我一定喜歡狗,因為狗是動物的子類;但是我喜歡狗,不能據此斷定我喜歡動物,因為我並不喜歡老鼠,雖然它也是動物。

繼續在前面兩章的ImageLoader為例:


上圖MemoryCache、DiskCache、DoubleCache都實現了ImageCahe介面,ImageLoader類需要一個ImageCahe類,而上面的三種具體實現Cache類都可以替換ImageCache的工作,並且能夠保證行為的正確性。所以ImageCache建立了獲取快取圖片、儲存快取圖片的介面規範,MemoryCache等根據介面規範實現了相應的功能,使用者只需要在使用時指定具體的快取物件就可以動態地替換ImageLoader中的快取策略。這就使得ImageLoader的快取系統具有了無限的可能性,也就是保證了可擴充套件性。

如果當ImageLoader中的setImageCache(ImageCache cache)中的cache物件不能夠被子類所替換,那麼使用者就無法設定不同的快取物件以及使用者也無法自定義自己的快取實現。里氏替換原則就為這類問題提供了指導原則,也就是建立抽象,通過抽象建立規範,具體的實現在執行時替換掉抽象,保證系統的高擴充套件性、靈活性。開閉原則和里氏替換原則往往是生死相依、不棄不離的,通過里氏替換來達到對擴充套件開放,對修改關閉的效果。所以,這兩個原則都同時強調了一個OOP的重要特性——抽象,因此,在開發過程中運用抽象是走向程式碼優化的重要一步。

  在使用里氏代換原則時需要注意如下幾個問題:

      (1)子類的所有方法必須在父類中宣告,或子類必須實現父類中宣告的所有方法。根據里氏代換原則,為了保證系統的擴充套件性,在程式中通常使用父類來進行定義,如果一個方法只存在子類中,在父類中不提供相應的宣告,則無法在以父類定義的物件中使用該方法。

      (2)  我們在運用里氏代換原則時,儘量把父類設計為抽象類或者介面,讓子類繼承父類或實現父介面,並實現在父類中宣告的方法,執行時,子類例項替換父類例項,我們可以很方便地擴充套件系統的功能,同時無須修改原有子類的程式碼,增加新的功能可以通過增加一個新的子類來實現。里氏代換原則是開閉原則的具體實現手段之一。

 讓專案擁有變化的能力——依賴倒置原則

依賴倒置原則英文全稱是Dependence Inversion Principle,簡稱DIP。抽象不應該依賴於細節,細節應當依賴於抽象。換言之,要針對介面程式設計,而不是針對實現程式設計。賴倒置原則指代了一種特定的解耦形式,使得高層次的模組不依賴於低層次的模組的實現細節的目的,依賴模組被顛倒了。這個概念有點不好理解,這到底是什麼意思呢? 
依賴倒置原則的幾個關鍵點:

  • 高層模組不應該依賴低層模組,兩者都應該依賴其抽象;
  • 抽象不應該依賴細節;
  • 細節應該依賴抽象。

在Java語言中,抽象就是指介面或抽象類,兩者都是不能直接被例項化的;細節就是實現類,實現介面或繼承抽象類而產生的類就是細節,其特點就是,可以直接被例項化,也就是可以加上一個關鍵字 new 產生一個物件。高層模組就是呼叫端,低層模組就是具體實現類。依賴倒置原則在 Java 語言中的表現就是:模組間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,其依賴關係是通過介面或抽象類產生的。這又是一個將理論抽象化的例項,其實一句話就可以概括:面向介面程式設計,或者說是面向抽象程式設計,這裡的抽象指的是介面或者抽象類。面向介面程式設計是面向物件精髓之一。

如果在類與類直接依賴於細節,那麼它們之間就有直接的耦合,當具體實現需要變化時,意味著在這要同時修改依賴者的程式碼,並且限制了系統的可擴充套件性。在講解單一原則時,開始ImageLoader程式碼如下:

public class ImageLoader {
    // 記憶體快取 ( 直接依賴於細節 )
    MemoryCache mMemoryCache = new MemoryCache();
     // 載入圖片到ImageView中
    public void displayImage(String url, ImageView imageView) {
       Bitmap bmp = mMemoryCache.get(url);
        if (bmp == null) {
            downloadImage(url, imageView);
        } else {
            imageView.setImageBitmap(bmp);
        }
    }

    public void setImageCache(MemoryCache cache) {
        mCache = cache ;
    }
    // 程式碼省略
}

ImageLoader直接依賴於MemoryCache,這個MemoryCache是一個具體實現,而不是一個抽象類或者介面。這導致了ImageLoader直接依賴了具體細節,當MemoryCache不能滿足ImageLoader而需要被其他快取實現替換時,此時就必須修改ImageLoader的程式碼。而後面引入ImageCahe這個介面後,不管怎麼修改MemoryCache類,都不用修改其依賴於ImageCahe類的ImageLoader類,最後的程式碼如下:

public interface ImageCache{
   void put(String url,Bitmap bitmap);
   Bitmap get(String url);
}

public class ImageLoader {
    // 圖片快取
    ImageCache mImageCache = null;
    
    public void setImageCache(ImageCache cache){
        mImageCache = cache;
    }
   
    public  void displayImage(final String url, final ImageView imageView) {
        if(mImageCache != null){
            Bitmap bitmap = mImageCache.get(url);
            if(bitmap != null){
                imageView.setImageBitmap(bitmap);
                return;
            }
        }
        downLoadImage()
     }
}

所以依賴倒轉原則要求我們在程式程式碼中傳遞引數時或在關聯關係中,儘量引用層次高的抽象層類,即使用介面和抽象類進行變數型別宣告、引數型別宣告、方法返回型別宣告,以及資料型別的轉換等,而不要用具體類來做這些事情。為了確保該原則的應用,一個具體類應當只實現介面或抽象類中宣告過的方法,而不要給出多餘的方法,否則將無法呼叫到在子類中增加的新方法。

程式碼github地址:點選開啟連結

更多精彩Android技術可以關注我們的微信公眾號,掃一掃下方的二維碼或搜尋關注公共號: Android老鳥                                                 

相關推薦

面向對象設計原則之四:依賴倒置原則

ron 通過 發生 需要 系統 面向對象設計 啟動 模塊 == 依賴倒置原則 所謂依賴倒置原則(Dependence Inversion Principle )就是要依賴於抽象,不要依賴於具體。簡單的說就是對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實

以C/C++語法淺談六大設計原則(一)——依賴倒置原則(Dependence Inversion Principle)

一. 前言 眾所周知,在軟體開發過程中,我們的六大設計原則與二十三種設計模式可以說是我們開發的思想精髓。然而,網上或者書本大多數的資料都是以java、python等其他語言語法進行介紹與闡述,很少有以C/C++的語法進行深入介紹。鑑於此,本人以淺薄的見識對這些精妙的思想做以總結,方便

SOLDI原則之DIP:依賴倒置原則

本篇介紹軟體設計原則之一DIP:依賴倒置原則。很多知識回頭來看會有新的理解。看到一句話,一段文字,一個觀點有了新的理解,醍醐灌頂的感覺。這種感覺像是一種驚喜。古語說:溫故而知新。 DIP:依賴倒置原則 a.高層模組不應該依賴於低層模組。二者都應該依賴於抽象。 b.抽象不應該依賴於細節。細節應該依

面向物件六大原則----里氏替換原則,依賴倒置原則

單一職責原則 英文名稱是Single Responsibility Principle,簡稱SRP 開閉原則英文全稱是Open Close Principle,簡稱OCP 里氏替換原則 英文全稱是Liskov Substitution Principle,簡稱LSP 依賴倒置原則 英文全稱是Depe

面向物件設計原則--里氏替換原則(LSP)和依賴倒置原則(DIP)

面向物件設計原則–里氏替換原則(LSP)和依賴倒置原則(DIP) tags:設計模式 LSP–inheritance should ensure that any property prove

[面向物件六大原則] 里氏替換原則(LSP)

里氏替換原則 - Liskov Substitution Principle定義一:如果對每一個型別為S的物件O1,都有型別為T的物件O2,使得以T定義的所有程式P在所有的物件O1都替換成O2時,程式P的行為沒有發生變化,那麼型別S是型別T的子型別。定義二:所有引用基類的地方

面向物件六大原則(三):依賴倒置原則

出處:http://blog.csdn.net/zhengzhb/article/details/7289269 定義:高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。 問題由來:類A直接依賴類B,假如要將類A改為依賴類C,則必須通

面向物件設計原則 依賴倒置原則(Dependency Inversion Principle)

依賴倒置原則(Dependence Inversion Principle)是程式要依賴於抽象介面,不要依賴於具體實現。 簡單的說就是要求對抽象進行程式設計,不要對實現進行程式設計,這樣就降低了客戶與實現模組間的耦合。   面向過程的開發

第2章 面向物件的設計原則(SOLID):3_依賴倒置原則(DIP)

3. 依賴倒置原則(Dependence Inversion Principle,DIP) 3.1 定義 (1)要依賴抽象,不要依賴具體的實現類。簡單的說就是對抽象(或介面)進行程式設計,不要依賴實現進行程式設計,這樣就降低了客戶與實現模組間的耦合。包含3層含義:   ①高層模組不應依賴

JAVA中OOAD(面向物件分析與設計依賴倒置原則)程式碼例項

簡介:什麼是依賴倒置原則? 軟體設計中,多層次之間相互依賴關係需要倒置為抽象類或介面,而不是直接依賴於具體的實現。 具體表現為: 1、上層模組不應該直接依賴下層實現,而應該依賴下層的抽象 2、每一個單獨的層次,抽象不應該依賴於細節,而細節應該依賴於抽象。 現在有一個使用者類UserBea

面向物件六大原則之單一

單一職責原則-SRP(Single Responsibility Principle) 通俗的說,即一個類只負責一項職責 如:類T負責兩個不同的職責:職責P1,職責P2。當由於職責P1需求發生改變而需要修改類T時有可能會導致原本執行正常的職責P2功能發生故障。 如:對資料庫的增刪查改,對資料

面向物件的五大設計原則依賴倒置原則

依賴倒置原則(depend ence inversion principle,簡稱DIP),簡單來說就是將依賴關係倒置為依賴介面,具體就是,上層模組不應該依賴於下層模組,它們共同依賴於一個抽象(父類不能依賴子類,應該共同依賴於抽象類)。抽象不能依賴於具體,但是具體應該依賴於抽象,我們要注意下,咱

java面向物件六大原則

面向物件特點:         1:將複雜的事情簡單化。         2:面向物件將以前的過程中的執行者,變成了指揮者。 &

設計模式六大原則:里氏替換原則(五)

里氏代換原則是由麻省理工學院(MIT)電腦科學實驗室的Liskov女士,在1987年的OOPSLA大會上發表的一篇文章《Data Abstraction and Hierarchy》裡面提出來的,主要闡述了有關繼承的一些原則,也就是什麼時候應該使用繼承,什麼

Android 面向物件六大設計原則之單一職責原則

1.單一職責原則簡介單一職責原則(SRP:Single responsibility principle)又稱單一功能原則,面向物件六個基本原則(SOLID)之一。它規定一個類應該只有一個發生變化的原因

面向物件六大原則——單一職責原則

什麼是單一職責原則(Single Responsibility Principle, SRP)  在講解什麼是單一職責原則之前,我們先說一個例子,吊一下口味:我們在做專案的時候,會接觸到使用者,機構,角色管理這些模組,基本上使用的都是RBAC模型(Role-Ba

【設計模式】面向物件六大原則

主要內容 關於面向物件六大原則 單一職責原則(Single Responsibility Principle) 縮寫為SRP。 對於一個類而言,應該僅有一個引起它變化的原因。或者說一個類中應該是一組相關性很高的函式、資料的封裝。大意就是一個類應該只做一件事情,這就是職

面向物件六大設計原則

最新在閱讀《Android原始碼設計模式解析與實戰》一書,我覺得寫的很清晰,每一個知識點都有示例,通過示例更加容易理解。書中的知識點有些都接觸過,有的沒有接觸過,總之,通過閱讀這本書來梳理一下知識點,可能有些東西在專案中一直在使用,然並不能籠統,清

Java設計模式之——面向物件六大原則

面向物件六大原則: 設計模式六大原則(1):單一職責原則 設計模式六大原則(2):開閉原則 設計模式六大原則(3):里氏替換原則 設計模式六大原則(4):依賴倒置原則 設計模式六大原則(5):介面隔離原則 設計模式六大原則(6):迪米特原則 設計模式六大

面向對象設計原則四:依賴倒置原則

設計原則 面向 dip 定性 穩定 要求 這樣的 覆蓋 通過 依賴倒置原則(DIP) 定義:高層模塊不應該依賴底層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。   好處:穩定性、可維護性、可擴展性。  概述:DI就是依賴倒置的意思,也可稱