架構設計基礎知識整理

Jacks Blog發表於2016-10-28

星星點點的知識點,很早就想做這塊整理了,持續維護…

I. 原則:

靈活運用,而非刻意遵循

1. 基礎原則

儘量少的重複程式碼,低耦合(儘量小的影響),高內聚
模組,可小到一個類,大到一個系統

模組間耦合因素

構建架構時,需要謹慎耦合的因素

  • 模組間呼叫
  • 模組間傳遞的資料量
  • 模組間控制
  • 模組間介面複雜度

模組間耦合從弱到強順序

構建架構或簡單的類時,需要根據實際情況儘量契合弱的模組間耦合關係
做到職責分明,簡單輕量,儘量少的潛在性的資料流動,儘量少的相互影響,避免牽一髮而動全身

  1. 非直接耦合: 相互之間沒有直接關係,而是由第三方模組控制和呼叫
  2. 資料耦合: 通過傳遞java的內建資料型別通訊
  3. 標記耦合: 都引用了共同的資料結構,並且通過傳遞該資料結構通訊
  4. 控制耦合: 通過傳遞開關、標誌、名字等控制資訊,明顯的控制選擇另一個模組的功能
  5. 外部耦合: 都訪問一個java的內建資料型別的全域性變數
  6. 公共耦合: 都訪問了一個公共程式碼塊( 全域性資料結構、公共通訊區、記憶體公共覆蓋區等)
  7. 內容耦合: 一個模組直接修改另外一個模組的資料。

降低耦合度的方法

  • 少用類繼承,多用類介面隱藏實現細節
  • 模組功能儘量單一
  • 拒絕重複程式碼
  • 儘量不使用全域性變數(Android中的全域性變數會有一些坑,因為Attach在ClassLoader上的,因此根據不同ROM的優化,可能會在未預料的情況被unload,導致資料丟失)
  • 類成員變數與方法少用public,多用private
  • 儘量不用硬編碼(如 字串放到 res/string.xml,SQL語句做一層基於業務的封裝供上層使用)
  • 使用設計模式,儘量讓模組間的耦合關係保證在資料耦合或更弱

2. 原則彙總

原則 基本概念 解決問題 基本實現
開閉原則 對擴充套件開發,對修改關閉 實現熱拔插,解耦方式 介面、抽象
里氏代換原則 子類是父類的具體抽象,抽象並可代表父類(Is-A) 解釋抽象化的具體原則 繼承,抽象
依賴倒轉原則 針對介面程式設計,依賴於抽象不依賴於具體 易於擴充 介面程式設計時型別使用基類,而不使用具體實現的子類
介面隔離原則 使用多個隔離介面,比使用單個介面要好 降低耦合 封裝介面的時候,儘量用不同介面解決不同問題,儘量不要合用一個介面
迪米特法則 以實體為單位,實體之間的相互作用盡量的少 降低耦合 寫一個系統架構,或模組的時候,儘量少的對外依賴
合成複用原則 優先使用合成/聚合,而非繼承 可以通過引入抽象類更加靈活,相互耦合變小,更加簡單 儘量將已有物件納入到新物件中,成為新物件的一部分,而不使用繼承的方式進行復用,如 ClassLoader 中雙親委派架構

使用組合而非繼承的場景:

優先使用物件組合,而非繼承

  • Has-A的關係,而非Is-A的關係
  • 子類的主要目的是擴充父類,而非overridefinal,如果存在大量這種情況,改用組合
  • 引入工具類,而非繼承自工具類
  • 有可能或不確定 子類 有可能被替換為 另外一個類的子類的情況 ( 如果出現這種情況,就需要修改。因此還不如使用 組合,如果有類似需求,再 組合如新的物件,進行擴充即可)

繼承需要注意

當已經選擇使用繼承時,需要注意

  • 實現抽象方法,擴充新的特性方法,儘量少的過載父類非抽象方法
  • 過載父類非抽象方法時: 方法前置條件(方法形參)要比父類方法更寬鬆,方法後置條件(方法返回值)要比父類更嚴格

類之間的關係與UML表示

II. 常見的模式

1. MVC 與 MVP

From http://msdn.microsoft.com/en-us/library/ff647859.aspx

MVP(Model-View_Presenter)是MVC(Model-View_Controller)的一個子集。

  • MVC中Controller控制全域性事務,View將事件傳送給ControllerController處理完事件同步給Model(資料庫/資料模型),View是通過所繫結的Model的改變來重新整理自己。
  • MVP中PresenterView中獲取資料,重新整理Model,當Model中的資料發生改變後,Presenter讀取Model並重新整理View

2. MVVM

MVVM(View<->ViewModel->Model)

在Android中可以通過DataBinding,直接在Layout檔案中繫結其ViewModel

  • View: 佈局
  • ViewModel: 負責顯示資料(監聽到Model中的資料變化進行顯示),以及處理使用者互動(監聽View佈局中的使用者Action)
  • Model: 儲存內容

3. MVVM-C

MVVM-C(View-ViewModel-Callback-Model)

  • View: 佈局
  • Callback: 通常可以是FragmentActivity,用於處理使用者互動(監聽View佈局中的使用者Action)
  • ViewModel: 顯示資料(監聽Model中的資料變化進行顯示)
  • Model: 儲存內容

III. 設計模式

1. 工廠方法模式

2. 單例模式

Initialization-on-demand holder idiom

Wiki

效能高,執行緒安全 基於JVM Class Loader保證Class唯一性執行緒安全的模型

public class Something {
    private Something() {}

    private static class LazyHolder {
        private static final Something INSTANCE = new Something();
    }

    public static Something getInstance() {
        return LazyHolder.INSTANCE;
    }
} 

3. 建造者模式

與工廠模式區別是: 工廠模式關注構建單個型別型別;建造者模式關注構建符合型別物件。

4. 原型模式

當前物件對外提供拷貝方法

淺拷貝

除了基本資料型別外,其他型別的物件都只持有當前物件的引用,而非重新建立拷貝

Java中的Object#clone
  1. Object#clone()就已經提供了該物件的淺拷貝
  2. 如果需要使用Object#clone,需要類實現Clonable這個介面,來申明該類物件支援拷貝,否則會拋CloneNotSupportedException, 如果物件中存在佇列成員變數,佇列也需要實現Clonable

深拷貝

所有成員變數都將重新建立

方式一:

直接序列化(Java中基於JVM層級最簡單的讓物件支援序列化的方式,實現Serializable),拷貝二進位制流。

方式二(推薦):

基於Object#clone()將非基本資料型別以外的元素都實現深拷貝,挨個深拷貝返回。

5. 介面卡模式

6. 裝飾模式

7. 代理模式

8. 外觀模式

9. 橋接模式

10. 組合模式

11. 享元模式

12. 策略模式

13. 模板方法模式

14. 觀察者模式

相關文章