1. 程式人生 > >每天學一個,設計模式概要

每天學一個,設計模式概要

應用程序 松耦合 信用 blog 相同 detail 關系 fin 目的

題外話

  回想起大學學過一門課程《設計模式》,裏面描述了很多包含前人思想精華的設計模式,用於構建代碼。工作久了,雖然在寫嵌入式C,但也經常能發現設計模式的精妙之處。而這些構建軟件的思想,正是做底層軟件的人經常所缺乏的思想,或者說,很少有軟件復用、設計復用的意識。

  比如,現在要設計一個定時器,用於計時,當計時時間滿足條件時執行某項任務。假設硬件定時器中斷1ms,任務定時1s,可以用uint32_t taskTimer(初值0) 來作軟件定時器。

常規做法:

定義硬件定時器中斷處理

// eTimer.c

extern uint32_t taskTimer;

// 硬件定時中斷處理函數,1ms一次
interrupt void eTimerInterrupt() { taskTimer ++;   // 清除中斷... }

查詢軟件定時器並執行任務

// main.c或者任務模塊
#define TASK_TIME  1000

uint32_t taskTimer = 0;  //任務定時器

int main()
{
    while(1){
        if(taskTimer > TASK_TIME  ) {
            taskTimer = 0; // 清楚定時器

            //執行任務...

        }
    }
    
return 0; }

  功能上,這個做法沒有問題。但是,一旦項目的復雜度高,或者參與的人數多了,會讓別人、甚至自己都看不懂,造成很大的困擾;如果應用層代碼一旦有修改,比如換個變量名字,添加一個定時器,都需要修改底層。顯然,這是不合理的。比較合理的做法是,底層應該是調用硬件驅動,給上層以接口形式提供服務,而不是強迫底層必須了解上層的細節,修改上層時也必須修改底層。

  試想,如果操作系統不得不關註應用程序具體是如何使用某項功能的,而且應用的功能修改,操作系統底層必須修改,這種設計後果有多可怕。而處理這個問題有一個很不錯的思路:就是將應用的定時器功能委托給底層硬件定時器模塊,而底層只提供接口,不關註應用的使用細節。

沒有經過封裝的用法:

技術分享圖片

經過委托模式思想封裝的用法:

技術分享圖片

參考

1. 設計模式六大原則 | 博客園

2. 設計模式六大原則

3. 設計模式六大原則 | CSDN

設計模式

總原則: 低耦合,高內聚;對擴展開放,對修改關閉。

六大原則

1. 單一職責原則

應該有且只有一個原因引起類的變化。簡單來說,一個類負責一項職責,功能要單一。

場景:比如一個程序員既要負責編碼,又要負責測試,那麽編碼出現問題的時候,就容易影響到測試;測試出問題的時候,就容易影響到編碼。如果程序員只負責一項工作,那麽就會,

優點:提高可擴展性、可維護性,降低類的復雜度。

2. 裏氏替換原則

只要父類出現的地方,一定可以使用子類,而且不會出現任何異常。這樣,使用者不需要知道是父類還是子類。

場景:商場為客戶(人)提高購物場所,任何人都可以進去購物。如果非要針對每個人的職業、年齡、身體狀況進行區分判斷、對待,那麽這個工作量無疑是巨大的。而且是不安全的,因為商場不得不針對實際情況修改驗證規則。

優點:程序健壯性增強;即使增加不同子類,不影響原類運行。

3. 依賴倒置原則

高層模塊不依賴底層模塊,二者都應該依賴抽象;抽象不應該依賴細節,細節應該依賴抽象。

簡而言之,對接口編程,而不是對實現編程。

場景:筆記本電腦雖然每個型號的充電插座端接口不一定相同,有TYPE-C的,有圓孔的,還有方口的,不過都會根據220V電源提供充電插頭(接口),否則設計比較的時候按每個筆記本不同細節來決定電源電壓,就會導致筆記本不通用,甚至難以充電。

優點:實現模塊松耦合;在大的項目效果明顯,並行開發更友好。

4.接口隔離原則

類之間的依賴關系應建立在最小的接口上。

簡而言之,接口方法盡量少而小,只留需要的,去掉不需要的。只暴露給調用他的類所需要的方法。

場景:客戶購車,只關心價格、外觀、駕駛性能等特性,如果非讓客戶去了解每個零部件供應商、工作原理,甚至制造過程,勢必會導致客戶所識車臃腫、復雜,而且對客戶的要求也更高。

優點:提高內聚,減少對外交互;

5. 迪米特法則

類間解耦。

通俗地,一個類對自己依賴的類知道的越少越好。

場景:公立銀行或醫院就是一個很好的設計,不用關心銀行/醫院的架構是怎樣的,財務報表是怎麽表現的,有國家信用支撐,會相信存在銀行的錢不會輕易坑自己,去醫院看病不會坑害自己。

優點:低耦合,易擴展。

6. 開放封閉原則

通過擴展來解決需求變化,而不是通過修改已有代碼。

場景:比如設計了一本書,已經通過出版社出版,後來發現書中內容有誤,如果要修改原書內容,就要召回所有書籍,重新印刷,但是這個工作量是巨大的,而且成本非常高。一種更好的方式是,在官網再擴展出一本勘誤,這樣有疑問的人可以去官網查詢。

優點:降低修改成本;

每天學一個,設計模式概要