設計模式六大原則概述

来源:http://www.cnblogs.com/luobao/archive/2017/02/22/6410844.html
-Advertisement-
Play Games

在面向對象軟體開發過程中,一些有經驗的軟體開發人員通常會採用設計模式來解決一些日常工作中的一些問題。設計模式是前人在軟體開發的過程中總結出來的一些解決問題的方案,並且經受住了時間的考驗和廣大軟體開發人員的不斷驗證。在軟體開發過程中,如果我們合理的使用設計模式可以提高代碼的復用性和可維護性。為了保證引 ...


 

  在面向對象軟體開發過程中,一些有經驗的軟體開發人員通常會採用設計模式來解決一些日常工作中的一些問題。設計模式是前人在軟體開發的過程中總結出來的一些解決問題的方案,並且經受住了時間的考驗和廣大軟體開發人員的不斷驗證。在軟體開發過程中,如果我們合理的使用設計模式可以提高代碼的復用性和可維護性。為了保證引用設計模式的合理性,我們在使用設計模式的時候一定要遵守面向對象設計的六大原則:單一職責原則、里氏替換原則、依賴倒轉原則、介面隔離原則、迪米特法則、開閉原則。設計模式就是通過實現這些原則,來達到代碼復用和增加可維護性的目的的。

  下麵分別介紹一下,設計模式的六大原則:

  單一職責原則(Single Responsibility Principle)

  定義單一職責原則規定一個類應該只有一個引起它發生變化的原因,即一個類應該只有一個職責。

  概述:如果一個類承擔多個職責,就相當於把這些職責耦合在了一起,如果其中的一個職責發生變化,有可能會影響到其它職責的正常運行。另外多個職責耦合在一起,還會降低類的復用性。在軟體開發過程中,如果想要避免這種現象的發生,就要使程式儘可能的遵守單一職責原則。

  問題由來:類T負責兩個不同的職責:職責P1,職責P2。當由於職責P1需求發生改變而需要修改類T時,有可能會導致原本運行正常的職責P2功能發生故障。也就是說職責P1和P2被耦合在了一起。

   產生問題的原因:程式設計不合理,或是職責擴散。

  ◆職責擴散:因為某種原因,某一職責被劃分為了多個粒度更細的職責。

  解決問題的方法:在寫程式時遵守單一職責原則,將不同的職責P1和P2分別封裝到不同的類或模塊中。能夠引起職責擴散的原因比較多,所以我們在前期進行程式設計的時候,應儘量的遵守單一職責原則。

  遵守單一職責原則能給我們的程式帶來的好處有:

  ◆讓一個類只負責一項職責,增強類的可讀性,提高系統的可維護性。

  ◆使我們能夠更容易的寫出符合高內聚低耦合核心思想的程式。

  註意事項:過度的遵守單一職責原則也會帶來一些弊端,遵守單一職責原則勢必會造成代碼量的增加。如果過度的使用,會使代碼顯得過於臃腫,當一個類的邏輯比較簡單,類中的方法數量比較少,並且不需要經常改動的時候,我們可以根據情況決定是否遵守單一職責原則。

   ■里氏轉換原則(Liskov Substitution Principle)

      定義:里氏轉換原則規定在程式裡面只要是基類出現的地方,都可以用子類進行替換。

  概述:里氏轉換原則描述的是父類和子類之間的關係,只有繼承關係存在時,里氏轉換原則才存在。里氏轉換原則是繼承復用的基礎,只有當子類可以替換掉父類,並且軟體單位的功能不受到任何影響時,父類才可以被覆用。

  問題由來:類A有一職責P1,現在需要對類A的職責進行擴展,新增加職責P2, 擴展職責的任務在子類B中完成,則子類B在完成新職責P2的同時,有可能會導致原有職責P1不能正常運行。

   解決問題的方法:在繼承時,遵守里氏轉換原則。類B繼承父類A時,除添加完成職責P2 的方法外,儘量不要重寫父類的非抽象方法。

   遵守里氏轉換原則能給我們的程式帶來的好處有:

  ◆子類繼承父類之後,可以增加自己特有的職責方法。

  ◆可以給面向抽象編程提供基礎,合理的遵守里氏轉換原則可以使我們的程式的穩定性和可擴展性更好。

  註意事項:在使用里氏轉換原則時需要註意的地方是,父類中凡是已經實現好的方法,實際上是在設定一系列的規範和契約,雖然它不強制要求所有的子類必須遵守這些契約,但是如果子類對這些非抽象方法任意修改,就會對整個繼承系統造成破壞。通俗的講就是:子類可以擴展父類的功能,但是不能改變父類的原有功能。

   ■依賴倒置原則(Dependency Inversion Principle)

      定義:在程式里高層模塊不應該依賴低層模塊,二者都應該依賴抽象;抽象不應該依賴細節,細節應該依賴抽象。

   概述:依賴倒置原則的核心思想是面向抽象編程,它基於這樣一個事實,相對於細節的多變性,抽象的東西要更加的穩定,以抽象為基礎搭建起來的架構比以細節為基礎搭建起來的架構要穩定的多。在C# 中,抽象指的是介面或抽象類,細節就是具體的實現類,使用介面或者是抽象類的目的是制定好規範和契約,而不去涉及任何具體的操作,把展現細節的任務交給它們的實現類去完成。

  問題由來:類A直接依賴類B,如果要將類A改為依賴類C,則必須通過修改類A的代碼來達成。這種情況,類A一般是高層模塊,負責複雜的業務邏輯;類B和類C是低層模塊,負責基本的原子操作;假如修改類A,會給程式帶來不必要的風險。

  解決問題的方法:讓類A依賴介面I,類B和類C各自實現介面I,類A通過介面I間接和類B或者類C發生聯繫,這樣就可以解決上面的問題。就像在三層架構中,讓業務邏輯層和資料庫連接層通過依賴抽象取得聯繫,這樣我們可以在資料庫連接層隨意切換數據源,而不影響業務邏輯層的正常功能。

  遵守依賴倒置原則能給我們的程式帶來的好處有:

  遵循依賴倒置原則可以降低類之間的耦合性,提高系統的穩定性,降低因修改程式造成的風險。採用依賴倒置原則給多人並行開髮帶來了極大的便利,參與協作開發的人越多、項目越龐大,採用依賴倒置原則的意義就越大。

  註意事項: 在實際編程中,我們一般需要做到,低層模塊儘量都要有抽象類或介面,變數的聲明類型儘量是抽象類或介面,使用繼承時遵循里氏轉換原則。

   ■介面隔離原則(Interface Segregation Principle)

      定義:客戶端不應該依賴它不需要的介面;一個類對另一個類的依賴應該建立在最小的介面上。

   概述: 在程式設計中,不要讓類去依賴一個含有它不需要的方法的介面。如果讓一個類依賴了含有它不需要的方法的介面,那麼就面臨著由於這些不需要的方法發生了改變,而給該類帶來的改變。一個類對另一個類的依賴應該建立在最小的介面上。

  問題由來:類A通過介面I依賴類B,類C通過介面I依賴類D,如果介面I對於類B和類D來說不是最小介面,則類B和類D必須去實現他們不需要的方法。

  解決問題的方法:採用介面隔離原則,將介面I拆分為獨立的幾個介面,類A和類C分別與他們需要的介面建立依賴關係。

  遵守依賴倒置原則能給我們的程式帶來的好處有:

  這樣避免了建立的介面過於臃腫,使子類中只需要去實現它自身需要的方法。可以提高程式設計的靈活性和介面的可復用性,降低類之間的耦合,避免和不相關的類發生聯繫。

  註意事項: 使用介面隔離原則需要註意的地方:介面應儘量的小,但是要有限度,對介面細化可以提高程式設計的靈活性,但是如果介面過小,則會造成介面數量過多,使設計複雜化,所以一定要適度。

   ■迪米特法則(Law of Demeter)

  定義:迪米特法則規定,一個對象應該對其它對象保持最少的瞭解。

  概述:迪米特法則又叫最少知道原則,通俗的講,就是一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類來說,無論邏輯多麼複雜,都應儘量的將邏輯封裝在類的內部,對外除了提供的public方法,不對外泄露任何信息。迪米特法則還有一個更簡單的定義就是只與直接的朋友通信。

  問題由來:類與類之間的關係越密切,耦合度就越大,類之間的相互影響也就越大。

  解決問題的方法:遵循迪米特法則,如果兩個類不需要直接通信,那麼這兩個類就不應當發生直接的相互引用。如果其中的一個類需要調用另一個類的某一個方法的話,可以通過一個中間類來調用。

  遵守迪米特法則能給我們的程式帶來的好處有:

  採用迪米特法則的程式設計可以降低類之間的耦合,由於每個類都減少了對其他類的依賴,因此,很容易使得系統的功能模塊更加的獨立,進而也就減少了類之間的相互依賴關係。

  註意事項:使用迪米特法則是為了降低類之間的耦合度,由於每個類都減少了不必要的依賴,因此的確可以降低耦合關係。但是凡事都要有度,雖然可以避免與非直接的類通信,但是要通信,必然會通過一個中間類來發生聯繫。如果過分的使用迪米特法則,就會產生大量的中間類,導致系統複雜度變大。所以在採用迪米特法則時要做好權衡,既要做到結構清晰,又要高內聚低耦合。

  ■開閉原則(Open Closed Principle)

   定義:一個軟體實體如類、模塊或函數應該對擴展開發,對修改關閉。

  概述:開閉原則是面向對象設計中最基礎的設計原則,它指導我們如何建立穩定靈活的系統。在實際開發的過程中,如果讓我們在設計階段就羅列出系統所有可能的行為,並把這些行為加入到抽象底層,這種做法是不現實的,也是不可取的。因此在做程式從設計的時候,我們應該接受修改,擁抱變化,使我們的代碼對擴展開放,對修改關閉。只有這樣做才能使我們的程式架構更穩定。

  問題由來:在軟體的生命周期內,我們會因為功能的變化或系統的升級等原因需要對軟體原有代碼進行修改。在修改時,可能會給原有代碼帶來嚴重的錯誤,導致我們不得不對整個功能進行重構,並且需要將原有代碼經過重新測試。

  解決問題的方法:遵守開閉原則,儘量通過擴展軟體實體的行為來實現變化,而不是修改已有的代碼來實現變化。

  遵守開閉原則能給我們的程式帶來的好處有:

  ◆使模塊具有更好的可復用性:

  在軟體完成以後,我們仍然可以對軟體進行擴展,可以通過增加新組件的方式非常靈活的加入新功能。因此,我們的軟體系統就可以通過不斷地增加新組件的方式,來滿足不斷變化的需求。

   ◆可維護性:

  對於已有的軟體系統的組件,特別是它的抽象底層我們不去做修改。這樣,我們就不用擔心軟體系統中原有組件的穩定性。這就使得在變化中,軟體系統有一定的穩定性和延續性。

  ■總結:

   在實際開發過程中,我們不應該刻板的遵守設計模式六大原則,而是應該根據實際情況靈活的應用。只有遵守的合理才能夠設計出可維護性好、復用性高的軟體系統。 通篇沒有代碼展示,似乎不太合理,下麵是我在練習時寫的一個完整的項目,托管在了github(SafetyMS) 上,裡面的程式設計基本上符合了設計模式的六大原則。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • /* 計算球體積 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 151765 Accepted Submission(s): 60772 Pr ...
  • 參考文章:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html java參數有值類型和引用類型兩種。所以java參數的傳值也就從這兩個方面分析。 從記憶體模型來說參數傳遞更為直觀一些,這裡涉及到兩種類型的記憶體:棧記憶體(stack)和堆記憶體(heap) ...
  • 頁面里經常要用到文件上傳的功能,而且要求頁面不刷新,先說一下原理:頁面里放一個file控制項和submit按鈕,外面用form表單包住,給form表單加上對應的屬性值,action、method、entype、name,到這一步,能上傳文件了,但是這樣上傳文件會刷新頁面,這不是我們想要的。我們要的是文 ...
  • 在學習Java的IO部分時有如下代碼: 一般都要將關閉資源.close()放在finally代碼塊中,防止try中發生異常資源沒有關閉,可上邊代碼報了IOException錯誤,當file.close();寫在try塊最後就沒有問題,原因是我把文件聲名FileInputStream file = n ...
  • 1、JDK JDK(Java Development Kit) 是 Java 語言的軟體開發工具包(SDK)。 JDK(Java Development Kit) 是 Java 語言的軟體開發工具包(SDK)。 SE(J2SE),standard edition,標準版,是我們通常用的一個版本,從J ...
  • 一、場景:有一個氣象站,檢測氣象後發佈氣象信息,有3個觀察者會接受氣象的發佈信息。 二、普通的處理方式: 三、觀察者模式處理方式: OO原則:為交互對象之間的松耦合設計而努力。(這個是第四條,後續還有幾條) 松耦合的設計之所以能讓我們建立有彈性的OO系統,能夠應對變化,是因為對象之間的互相依賴降到了 ...
  • 一、概述 建造者模式很容易讓人想到建房子,不管建剛需房、改善房還是別墅,它們都離不開地基、柱子、層面和牆體這些組成部分,建築工人就是把這些組成部分一個個建起來,最後連成一體建出一棟棟樓房。 來看看建造者模式的定義,將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建房子的過程 ...
  • 一:現實場景 有時候在開發的過程中,我們經常會根據某個狀態的值,寫出很多的ifelse邏輯,比如拿項目裡面的案例來說,如果當前發送的是彩信,此種狀態需要如何給 實體賦值,如果是簡訊,郵件又是其他方式的賦值,等等此類,這種情況下一般會寫出如下if判斷,對吧,真實代碼如下: 上面的代碼還是非常簡單明瞭的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...