日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深度总结:软件设计七大原则

發布時間:2023/12/14 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度总结:软件设计七大原则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

軟件設計七大原則

軟件設計原則是設計模式的基石。目的只有一個,降低對象之間的耦合,增加程序的可復用性、可擴展性、可維護性。

開閉原則 OCP

定義:軟件實體對擴展開放,對修改關閉。

  • 對擴展開發,意味著有新的需求或變化時,可以對現有代碼進行擴展,以適應新的情況。

  • 對修改關閉,意味著類一旦設計完成,就可以獨立的工作,而不要對其進行任何的修改。

在面向對象設計中,我們通常通過繼承和多態來實現OCP,即封裝不變部分。

比如需求要實現2種狀態的業務。

  • 如果用if else來判斷,那么后面加第三種狀態,就還需要在此接口上增加else邏輯,不符合開閉原則。

  • 用策略類實現,則定義策略接口,策略A和策略B為具體實現類,分別對應兩種狀態。假如下一次需求要實現第三種狀態,那么直接定義一個StrategyC實現類就可滿足。原有代碼不變,符合開閉原則。

詳情可點擊:策略模式文章

里氏替換原則 LSP

定義:程序中的父類型都可以正確的被子類型替換。

程序中的對象可以在不改變程序正確性的前提下被它的子類所替換,即子類可以替換任何基類能夠出現的地方,并且經過替換后,代碼還能正確工作。

根據LSP的定義,如果在程序中出現使用instanceof、強制類型轉換或者函數覆蓋,很可能意味著是對LSP的破壞。

假設定義一個抽象禽類,有一個飛翔方法fly(), 我們就可以自由的繼承禽類衍生出各種鳥兒,并調用其飛翔方法。如果鴕鳥加入禽類行列,繼承禽類,但不會飛,那么飛翔方法fly()就顯得多余。而且在所有禽類出現的地方,無法用鴕鳥替換(此時不滿足正確業務邏輯)。違反了里氏替換原則。

經過反思,是設計問題,禽類和飛翔無必然聯系,所以禽類不應該定義飛翔方法fly(),把禽類飛翔方法fly()抽離出去單獨定義飛翔接口Flyable。

對于有飛翔能力的鳥兒繼承禽類并實現飛翔接口。鴕鳥繼承禽類,但不實現飛翔接口,是否是鳥兒取決于是否繼承自禽類,能不能飛取決于是否實現飛翔接口。所有禽類出現的地方都可以用子類進行替換,所有飛翔接口出現的地方都可以被其替換為實現。

依賴倒置原則 DIP

定義:模塊之間交互應該依賴抽象,而非實現。

DIP要求高層模塊不應該依賴于底層模塊,二者都應該依賴于抽象。抽象不應該依賴細節,細節應該依賴抽象。

比如某個人喂養小動物,如果依賴了具體的實現,則每新增一個動物,需要在Person內加一個對應的方法。違背了開閉原則,也不符合依賴倒置原則。

重新修改后,如下。新增一個Birds抽象類,具體的動物繼承自父類Birds,Person中的方法參數依賴于抽象,而不是具體的實現。符合依賴倒置原則。

單一職責原則 SRP

定義:對任何類的修改只能有一個原因。換句話說,一個類只應該負責一項職責。

SRP要求每個軟件模塊職責要單一,衡量標準是模塊是否只有一個被修改的原因。職責越單一,被修改的原因就越少,模塊的內聚性就越高,被復用的可能性就越大,也更容易被理解。

舉例員工類 Employee,開發工作變了,需要修改Employee類,測試工作變了需要修改Employee類,不符合單一職責原則,類的復雜性也高。

  • 職責多,引起此類變化的原因也多。后續變更的風險就大。

  • 后續需求變更,會造成職責的混亂,類結構的不穩定。

改造后,類的職責單一。開發者的職責就是“寫代碼”,那么對其進行的修改只有與“寫代碼”相關的一個原因(畫類圖也是為了指導代碼落地),這樣才能確保類職責的單一性原則。

同時,類與類之間雖有著明確的職責劃分,但又一起合作完成任務,它們保持著一種“對立且統一”的辯證關系。

  • 以責任鏈模式為例,每個處理者類職責清晰,只處理與自己職責相關的業務。

  • 以員工類為例,拆分后,各個員工完成相應的職責,共同保障項目上線。

這種清晰的職責范圍劃分就是單一職責原則的最佳實踐。符合單一職責原則的設計能使類具備高內聚性,讓單個模塊變得簡單易懂,如此才能增強代碼的可讀性和可復用性。并提高系統的易維護性和易測試性。

上面的例子是類職責單一,那么微服務劃分也同理,采用單一職責原則,每個服務負責一塊業務。同一類業務的變更落在單個服務內變更

接口隔離原則 ISP

定義:客戶端對類的依賴基于最小接口,而不依賴不需要的接口。

接口隔離原則認為不能強迫用戶去依賴那些他們不使用的接口。換句話說,使用多個專門的接口比使用單一的總接口要好。做接口拆分時,也要盡量滿足單一職責原則。將外部依賴減到最少,降低模塊間的耦合。

比如類A只需要使用方法1、方法3,類B只需要使用方法2、方法4,但在源代碼層次上與所有方法形成依賴關系。這種依賴意味著我們對接口I的方法2修改,即使不會影響A所依賴的方法1、方法3的功能,也會導致它需要重新部署和編譯。

改造后,類A不需要用到方法2、方法4,就可以選擇不依賴它們。代碼更加清晰,接口職責更加明確。

迪米特法則 LOD

定義:一個類對于其它類知道的越少越好。

迪米特法則也被稱為最少知識原則,它提出一個模塊對其他模塊應該知之甚少,或者說模塊之間應該彼此保持陌生,甚至意識不到對方的存在,以此最小化、簡單化模塊間的通信,并達到松耦合的目的。

反之,模塊之間若存在過多的關聯,那么一個很小的變動則可能會引發蝴蝶效應般的連鎖反應,最終會波及大范圍的系統變動。我們說,缺乏良好封裝性的系統模塊是違反迪米特法則的,牽一發動全身的設計使系統的擴展與維護變的舉步維艱。

門面模式和中介者模式是迪米特法則極好的范例。 Tomcat中 RequestFacade類就使用了外觀模式。RequestFacade是對Request類封裝,屏蔽內部屬性和方法,避免暴露。

合成復用原則 CRP

定義:優先使用合成/聚合,而不是類繼承。

比如對象的繼承關系是在編譯時就定義好了,所以無法在運行時改變從父類繼承的實現。子類的實現與它的父類有非常緊密的依賴關系,以至于父類實現中的任何變化必然會導致子類發生變化。當你需要復用子類時,如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其它更適合的類替換。這種依賴關系限制了靈活性并最終限制了復用性。

合成(組合)和聚合都是關聯的特殊種類。

  • 聚合表示一種弱的擁有關系,體現的是A對象可以包含B對象,但B對象不是A對象的一部分;

  • 合成則是一種強大的“擁有”關系,體現了嚴格的部分和整體的關系,部分和整體的生命周期一樣。

合成/聚合復用原則好處:優先使用對象的合成/聚合將有助于你保持每個類被封裝,并被集中在單個任務上。這樣類和類繼承層次會保持較小規模。

舉例:手機軟件劃分可分為QQ、微信等,按品牌劃分可分為華為、小米等。如果同時考慮這兩種分類,其組合就很多。往下繼續擴展軟件、手機品牌,都會新增許多子類。違背了開閉原則,也限制了復用性。

用聚合關系實現的類圖:后面新增軟件,手機品牌類不用變更代碼。繼承的層次也少了。

參考資料

  • 劉韜:《秒懂設計模式》

  • 張建飛:《代碼精進之路:從碼農到工匠》

  • Robert C. Martin:《架構整潔之道》

  • 程杰:《大話設計模式》

  • 關注公眾號,后臺回復【筆記】獲取技術筆記PDF。

    ?

    總結

    以上是生活随笔為你收集整理的深度总结:软件设计七大原则的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。