007.設計原則與思想:總結

一.總結回顧面向對象、設計原則、編程規範、重構技巧等知識點

1. 面向對象
  1. 基於接口而非實現編程

應用這條原則,可以將接口和實現相分離,封裝不穩定的實現,暴露穩定的接口。上游系統面向接口而非實現編程,不依賴不穩定的實現細節,這樣當實現發生變化的時候,上游系統的代碼基本上不需要做改動,以此來降低耦合性,提高擴展性

  1. 多用組合少用繼承

(1). 爲什麼不推薦使用繼承?

繼承是面向對象的四大特性之一,用來表示類之間的 is-a 關係,可以解決代碼複用的問題。雖然繼承有諸多作用,但繼承層次過深、過複雜,也會影響到代碼的可維護性。在這種情況下,我們應該儘量少用,甚至不用繼承。

(2). 組合相比繼承有哪些優勢?

繼承主要有三個作用:表示 is-a 關係、支持多態特性、代碼複用。而這三個作用都可以通過組合、接口、委託三個技術手段來達成。除此之外,利用組合還能解決層次過深、過複雜的繼承關係影響代碼可維護性的問題。

(3). 如何判斷該用組合還是繼承?

如果類之間的繼承結構穩定,層次比較淺,關係不復雜,我們就可以大膽地使用繼承。反之,我們就儘量使用組合來替代繼承。除此之外,還有一些設計模式、特殊的應用場景,會固定使用繼承或者組合。

2. 貧血模型 VS 充血模型
  1. 貧血模型&&充血模型

我們平時做 Web 項目的業務開發,大部分都是基於貧血模型的 MVC 三層架構,在專欄中我把它稱爲傳統的開發模式。之所以稱之爲“傳統”,是相對於新興的基於充血模型的 DDD 開發模式來說的。基於貧血模型的傳統開發模式,是典型的面向過程的編程風格。相反,基於充血模型的 DDD 開發模式,是典型的面向對象的編程風格。

  1. 選用

對於業務不復雜的系統開發來說,基於貧血模型的傳統開發模式簡單夠用,基於充血模型的 DDD 開發模式有點大材小用,無法發揮作用。相反,對於業務複雜的系統開發來說,基於充血模型的 DDD 開發模式,因爲前期需要在設計上投入更多時間和精力,來提高代碼的複用性和可維護性,所以相比基於貧血模型的開發模式,更加有優勢。

  1. 區別

基於充血模型的 DDD 開發模式跟基於貧血模型的傳統開發模式相比,主要區別在 Service 層。在基於充血模型的開發模式下,我們將部分原來在 Service 類中的業務邏輯移動到了一個充血的 Domain 領域模型中,讓 Service 類的實現依賴這個 Domain 類。不過,Service 類並不會完全移除,而是負責一些不適合放在 Domain 類中的功能。比如,負責與 Repository 層打交道、跨領域模型的業務聚合功能、冪等事務等非功能性的工作

設計原則–SRP單一職責原則
  1. 單一職責原則

一個類只負責完成一個職責或者功能。單一職責原則通過避免設計大而全的類,避免將不相關的功能耦合在一起,來提高類的內聚性。

  1. 不滿足單一職責原則
  1. 類中的代碼行數、函數或者屬性過多;
  2. 類依賴的其他類過多或者依賴類的其他類過多;
  3. 私有方法過多;
  4. 較難給類起一個合適的名字;
  5. 類中大量的方法都是集中操作類中的某幾個屬性。
設計原則–OCP開閉原則
  1. 對擴展開放、修改關閉

添加一個新的功能,應該是通過在已有代碼基礎上擴展代碼(新增模塊、類、方法、屬性等),而非修改已有代碼(修改模塊、類、方法、屬性等)的方式來完成

  1. 如何做到“對擴展開放、修改關閉”?

我們要時刻具備擴展意識、抽象意識、封裝意識。在寫代碼的時候,我們要多花點時間思考一下,這段代碼未來可能有哪些需求變更,如何設計代碼結構,事先留好擴展點,以便在未來需求變更的時候,在不改動代碼整體結構、做到最小代碼改動的情況下,將新的代碼靈活地插入到擴展點上。

設計原則–LSP 裏式替換原則
  1. 里氏替換原則

裏式替換原則是用來指導繼承關係中子類該如何設計的一個原則。理解裏式替換原則,最核心的就是理解“design by contract,按照協議來設計”這幾個字。父類定義了函數的“約定”(或者叫協議),那子類可以改變函數的內部實現邏輯,但不能改變函數的原有“約定”。這裏的“約定”包括:函數聲明要實現的功能;對輸入、輸出、異常的約定;甚至包括註釋中所羅列的任何特殊說明。

設計原則–ISP 接口隔離原則
  1. 概述

客戶端不應該強迫依賴它不需要的接口。其中的“客戶端”,可以理解爲接口的調用者或者使用者。

  1. 理解“接口隔離原則”的重點是理解其中的“接口”二字。這裏有三種不同的理解。
  2. 接口集合

如果把“接口”理解爲一組接口集合,可以是某個微服務的接口,也可以是某個類庫的接口等。如果部分接口只被部分調用者使用,我們就需要將這部分接口隔離出來,單獨給這部分調用者使用,而不強迫其他調用者也依賴這部分不會被用到的接口。

  1. 單個 API 接口或函數

如果把“接口”理解爲單個 API 接口或函數,部分調用者只需要函數中的部分功能,那我們就需要把函數拆分成粒度更細的多個函數,讓調用者只依賴它需要的那個細粒度函數

  1. OOP中接口

如果把“接口”理解爲 OOP 中的接口,也可以理解爲面向對象編程語言中的接口語法。那接口的設計要儘量單一,不要讓接口的實現類和調用者,依賴不需要的接口函數

設計原則–DIP 依賴倒置原則
  1. 控制反轉
  2. 依賴注入

依賴注入和控制反轉恰恰相反,它是一種具體的編碼技巧。我們不通過 new 的方式在類內部創建依賴類的對象,而是將依賴的類對象在外部創建好之後,通過構造函數、函數參數等方式傳遞(或“注入”)給類來使用。

KISS、YAGNI 原則
  1. KISS 原則的中文描述是:儘量保持簡單。KISS 原則是保持代碼可讀和可維護的重要手段。KISS 原則中的“簡單“”並不是以代碼行數來考量的。代碼行數越少並不代表代碼越簡單,我們還要考慮邏輯複雜度、實現難度、代碼的可讀性等。而且,本身就複雜的問題,用複雜的方法解決,也並不違背 KISS 原則。除此之外,同樣的代碼,在某個業務場景下滿足 KISS 原則,換一個應用場景可能就不滿足了。

  2. KISS原則指導原則

不要使用同事可能不懂的技術來實現代碼;
不要重複造輪子,善於使用已經有的工具類庫;
不要過度優化。

DRY 原則
  1. 原則

中文描述是:不要重複自己,將它應用在編程中,可以理解爲:不要寫重複的代碼。

  1. 三種代碼重複的情況

實現邏輯重複、功能語義重複、代碼執行重複。實現邏輯重複,但功能語義不重複的代碼,並不違反 DRY 原則。實現邏輯不重複,但功能語義重複的代碼,也算是違反 DRY 原則。而代碼執行重複也算是違反 DRY 原則。

LOD原則
  1. 高內聚、松耦合

高內聚、松耦合”是一個非常重要的設計思想,能夠有效提高代碼的可讀性和可維護性,縮小功能改動導致的代碼改動範圍。“高內聚”用來指導類本身的設計,“松耦合”用來指導類與類之間依賴關係的設計。所謂高內聚,就是指相近的功能應該放到同一個類中,不相近的功能不要放到同一類中。相近的功能往往會被同時修改,放到同一個類中,修改會比較集中。所謂“松耦合”指的是,在代碼中,類與類之間的依賴關係簡單清晰。即使兩個類有依賴關係,一個類的代碼改動也不會或者很少導致依賴類的代碼改動。

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