設計模式初探之六大基本原則

前言

程序員技術精進之路上設計模式是繞不開的話題。儘可能多的使用設計模式可以讓我們的代碼更清晰,更有條理。現在較經常使用的設計模式有數種之多。這些設計模式大都遵循六大基本原則,分別是:

  • 單一職責原則
  • 開閉原則
  • 里氏替換原則
  • 依賴倒置原則
  • 接口隔離原則
  • 迪米特法則

如何理解這六大基本原則呢

單一職責原則

單一職責原則(Single Responsibility Principle, SRP):一個類只負責一個功能領域中的相應職責,或者可以定義爲:就一個類而言,應該只有一個引起它變化的原因。

說人話就是一個類或者方法最好只用來做一件事,比如我想蓋一件房子,我可以用一個類實現蓋房子的所有步驟,但是有兩個缺點,第一個不易閱讀,第二個沒法複用。第二天我想蓋棟大廈,又得重新寫一個更加複雜的類來實現,非常沒有效率。
但是假如我把蓋一個房子的所有步驟拆分開,拆分成打地基,建主體框架,埋線鋪設管道等,每個步驟又可以細分到拌水泥,砌磚等等。那麼我在蓋大廈時不就可以複用建房子的很多步驟了麼。這將大大節約開發時間。也可以方便應對今後產品需求的變更。

開閉原則

開閉原則(Open-Closed Principle, OCP):一個軟件實體應當對擴展開放,對修改關閉。即軟件實體應儘量在不修改原有代碼的情況下進行擴展。

任何代碼在不斷迭代的狀態下總會遇到需求的不斷變更,有時候明知道以前的代碼和數據架構很爛依然需要進行支持。這時候假如我們的低層遵循了開閉原則的話,我們可以做到在不改變底層架構的情況下通過擴展新的類型支持新的需求,避免很多可以預期會出現的bug,這將極大提升程序員的幸福感。這裏寫圖片描述

里氏替換原則

里氏代換原則(Liskov Substitution Principle, LSP):所有引用基類(父類)的地方必須能透明地使用其子類的對象。

里氏代換原則告訴我們,在軟件中將一個基類對象替換成它的子類對象,程序將不會產生任何錯誤和異常,反過來則不成立,如果一個軟件實體使用的是一個子類對象的話,那麼它不一定能夠使用基類對象。例如:我喜歡動物,那我一定喜歡狗,因爲狗是動物的子類;但是我喜歡狗,不能據此斷定我喜歡動物,因爲我並不喜歡老鼠,雖然它也是動物。
里氏代換原則是實現開閉原則的重要方式之一,由於使用基類對象的地方都可以使用子類對象,因此在程序中儘量使用基類類型來對對象進行定義,而在運行時再確定其子類類型,用子類對象來替換父類對象。

依賴倒置原則

依賴倒轉原則(Dependency Inversion Principle, DIP):抽象不應該依賴於細節,細節應當依賴於抽象。換言之,要針對接口編程,而不是針對實現編程。

依賴倒轉原則要求我們在程序代碼中傳遞參數時或在關聯關係中,儘量引用層次高的抽象層類,即使用接口和抽象類進行變量類型聲明、參數類型聲明、方法返回類型聲明,以及數據類型的轉換等,而不要用具體類來做這些事情。爲了確保該原則的應用,一個具體類應當只實現接口或抽象類中聲明過的方法,而不要給出多餘的方法,否則將無法調用到在子類中增加的新方法。
具體應儘量只實現事先定義在接口或抽象類中的方法而不增加更多私有的方法,以避免無法通過父類對象調用子類自定義方法的情況。

接口隔離原則

接口隔離原則(Interface Segregation Principle, ISP):使用多個專門的接口,而不使用單一的總接口,即客戶端不應該依賴那些它不需要的接口。

這個可以理解爲接口版的單一職責原則,即不宜將所有方法定義在總接口中,以免具體類需要實現的方法過多。應儘量保持接口的專一性,每個接口只負責一個方面。這裏寫圖片描述普通人的日常有吃飯,睡覺,洗澡等等,但假如我今天沒怎麼流汗,我就可以不實現洗澡接口,避免寫洗澡的具體實現了。

迪米特法則

迪米特法則(Law of Demeter, LoD):一個軟件實體應當儘可能少地與其他實體發生相互作用。

如果一個系統符合迪米特法則,那麼當其中某一個模塊發生修改時,就會盡量少地影響其他模塊,擴展會相對容易,這是對軟件實體之間通信的限制,迪米特法則要求限制軟件實體之間通信的寬度和深度。迪米特法則可降低系統的耦合度,使類與類之間保持鬆散的耦合關係。

迪米特法則還有幾種定義形式,包括:不要和“陌生人”說話、只與你的直接朋友通信等,在迪米特法則中,對於一個對象,其朋友包括以下幾類:
1 當前對象本身(this);
2 以參數形式傳入到當前對象方法中的對象;
3 當前對象的成員對象;
4 如果當前對象的成員對象是一個集合,那麼集合中的元素也都是朋友;
5 當前對象所創建的對象。
迪米特法則要求我們在設計系統時,應該儘量減少對象之間的交互,如果兩個對象之間不必彼此直接通信,那麼這兩個對象就不應當發生任何直接的相互作用,如果其中的一個對象需要調用另一個對象的某一個方法的話,可以通過第三者轉發這個調用。簡言之,就是通過引入一個合理的第三者來降低現有對象之間的耦合度。

在具體開發環境中的應用

任何具體設計模式都是對這些原則的實踐,就像笑傲江湖裏的華山劍氣二宗一樣,氣爲本,劍爲用。在這裏就是原則爲本,具體模式爲用。在程序開發中常用的一些設計模式有單例模式,構建者模式,工廠模式等。
我曾用構建者模式來創建我們app自定義風格的dialog,也是模仿android原生的AlertDialogBuilder來做的,可以避免每次用到都要重新寫佈局文件的尷尬。Builder模式的特色就是將title,content,click事件等都保存到構造者中,讓它來構造所需要的dialog。

public Builder setTitle(String title){
            dialogViewModel.title = title;
            return this;
        }

每次set之後都要返回Builder對象本身,別的好像也沒什麼好說的了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章