設計模式 - 幾個原則

What

設計模式(Design Pattern)是前人針對面向對象設計中反復出現的問題,總結出的設計套路。這個術語是在1990年代由Erich Gamma等人從建筑設計領域引入到計算機科學中來的。

算法不是DP,算法致力于解決本質問題,而DP更側重布局設計問題;DP不能讓算法變得更準確或者更高效,但可能會讓算法實現的更優雅(好吧,更可復用、好維護、易擴展、更可靠等)。

Why

正確使用設計模式具有以下優點。

  • 提高思維和設計能力,進而影響編程能力
  • 使程序設計更加標準化、代碼編制更加工程化,進而大大提高軟件開發效率
  • 使設計的代碼可重用性高、可讀性強、可靠性高、靈活性好、可維護性強。

6大設計原則(對封裝、繼承、多態的進一步原則指導)

  • 開閉原則:軟件實體應當對擴展開放,對修改關閉(避免影響已有的邏輯)
  • 單一職責原則:類的職責盡量專注單一,從而達到內聚松耦合
  • 里氏替換原則:只要父類出現的地方子類就可以出現,且替換成子類也不會出現任何錯誤或者異常(沒事別瞎繼承!!)
  • 依賴倒置原則:面向接口編程,而非面向實現編程(高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象)
  • 接口隔離原則:不要建立臃腫龐大的接口。即接口盡量細化,客戶端不應該被迫依賴于它不使用的方法
  • 迪米特法則: 一個對象應該對其他對象(接口、參數、返回值等)有最少的了解(為了解耦、安全等)

開閉原則

軟件實體應當對擴展開放,對修改關閉(避免影響已有的邏輯)

軟件實體包括以下幾個部分:

  • 模塊
  • 類與接口
  • 方法

實現方法:抽象約束、封裝變化

即通過接口或者抽象類為軟件實體定義一個相對穩定的抽象層,而將相同的可變因素封裝在相同的具體實現類中。
因為抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟件架構的穩定。
而軟件中易變的細節可以從抽象派生來的實現類來進行擴展,當軟件需要發生變化時,只需要根據需求重新派生一個實現類來擴展就可以了。

舉例:Windows 的桌面主題設計

單一職責原則

類的職責盡量專注單一,從而達到高內聚低耦合

該原則提出對象不應該承擔太多職責,如果一個對象承擔了太多的職責,至少存在以下兩個缺點:

  • 一個職責的變化可能會削弱或者抑制這個類實現其他職責的能力;
  • 當客戶端需要該對象的某一個職責時,不得不將其他不需要的職責全都包含進來,從而造成冗余代碼或代碼的浪費。

實現方式:找準核心實體,發現多重職責,進行分離

單一職責原則是最簡單但又最難運用的原則,需要設計人員發現類的不同職責并將其分離,再封裝到不同的類或模塊中。
而發現類的多重職責需要設計人員具有較強的分析設計能力和相關重構經驗。

舉例 :學生工作

分析:大學學生工作主要包括學生生活輔導和學生學業指導兩個方面的工作,其中生活輔導主要包括班委建設、出勤統計、心理輔導、費用催繳、班級管理等工作,學業指導主要包括專業引導、學習輔導、科研指導、學習總結等工作。如果將這些工作交給一位老師負責顯然不合理,正確的做 法是生活輔導由輔導員負責,學業指導由學業導師負責

里氏替換原則

只要父類出現的地方子類就可以出現,且替換成子類也不會出現任何錯誤或者異常(沒事別瞎繼承!!)

子類可以擴展父類的功能,但不能改變父類原有的功能。

實現方式:取消原來的繼承關系,重新設計它們之間的關系

舉例:幾維鳥不是鳥”

不合理的繼承關系:


不符合里氏替換的繼承

較合理的繼承關系:


符合里氏替換的繼承

依據:
鳥一般都會飛行,如燕子的飛行速度大概是每小時 120 千米。但是新西蘭的幾維鳥由于翅膀退化無法飛行。假如要設計一個實例,計算這兩種鳥飛行 300 千米要花費的時間。顯然,拿燕子來測試這段代碼,結果正確,能計算出所需要的時間;但拿幾維鳥來測試,結果會發生“除零異常”或是“無窮大”,明顯不符合預期

正確的做法是:取消幾維鳥原來的繼承關系,定義鳥和幾維鳥的更一般的父類,如動物類,它們都有奔跑的能力。幾維鳥的飛行速度雖然為 0,但奔跑速度不為 0,可以計算出其奔跑 300 千米所要花費的時間。

依賴倒置原則

面向接口編程,而非面向實現編程(高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象);這里的抽象指的是接口或者抽象類,而細節是指具體的實現類。

實現

  • 每個類盡量提供接口或抽象類,或者兩者都具備。
  • 變量的聲明類型盡量是接口或者是抽象類。
  • 任何類都不應該從具體類派生。
  • 使用繼承時盡量遵循里氏替換原則。

舉例:顧客購物程序

接口隔離原則

不要建立臃腫龐大的接口。即接口盡量細化,客戶端不應該被迫依賴于它不使用的方法;

實現

  • 接口的粒度大小定義合理
  • 不宜定義過小,否則會造成接口數量過多,使設計復雜化;
  • 使用多個專門的接口還能夠體現對象的層次,因為可以通過接口的繼承,實現對總接口的定義。

舉例:學生成績管理程序

學生成績管理程序一般包含插入成績、刪除成績、修改成績、計算總分、計算均分、打印成績信息、査詢成績信息等功能,如果將這些功能全部放到一個接口中顯然不太合理,正確的做法是將它們分別放在輸入模塊、統計模塊和打印模塊等 3 個模塊中。


迪米特法則

一個對象應該對其他對象(接口、參數、返回值等)有最少的了解(為了解耦、安全等)
但是,過度使用迪米特法則會使系統產生大量的中介類,從而增加系統的復雜性,使模塊之間的通信效率降低。

實現

從依賴者的角度來說,只依賴應該依賴的對象。
從被依賴者的角度說,只暴露應該暴露的方法。

舉例:明星與經紀人的關系實例

明星由于全身心投入藝術,所以許多日常事務由經紀人負責處理,如與粉絲的見面會,與媒體公司的業務洽淡等。這里的經紀人是明星的朋友,而粉絲和媒體公司是陌生人,所以適合使用迪米特法則


組成聚合原則

它要求在軟件復用時,要盡量先使用組合或者聚合等關聯關系來實現,其次才考慮使用繼承關系來實現。

實現

合成復用原則是通過將已有的對象納入新對象中,作為新對象的成員對象來實現的,新對象可以調用已有對象的功能,從而達到復用。

舉例:汽車分類管理

汽車按“動力源”劃分可分為汽油汽車、電動汽車等;按“顏色”劃分可分為白色汽車、黑色汽車和紅色汽車等。如果同時考慮這兩種分類,其組合就很多。

不好的設計


不好的設計

推薦的設計


推薦的設計
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 單一職責 定義 一個類只負責一項職責 里氏替換 定義 引用基類的地方必須能透明地使用其子類的對象 核心思想 子類可...
    visionarywind閱讀 508評論 0 0
  • 目錄: 設計模式六大原則(1):單一職責原則 設計模式六大原則(2):里氏替換原則 設計模式六大原則(3):依賴倒...
    加油小杜閱讀 735評論 0 1
  • 設計模式六大原則 設計模式六大原則(1):單一職責原則 定義:不要存在多于一個導致類變更的原因。通俗的說,即一個類...
    viva158閱讀 779評論 0 1
  • 轉載標注聲明:http://www.uml.org.cn/sjms/201211023.asp 目錄:[設計模式六...
    Bloo_m閱讀 731評論 0 7
  • 要建六座千年之城,將要花費百萬億的資金,每座千年之城基礎建設資金高達十萬億以上,錢從何來?用什么辦法籌集?...
    改變天地的蟲閱讀 736評論 8 51