主頁 > 軟體設計 > 我用過的設計模式(1)-- 本門心法

我用過的設計模式(1)-- 本門心法

2021-02-08 14:21:37 軟體設計

在這里插入圖片描述

文章目錄

    • 單一職責原則
      • 什么是“單一職責原則”?
      • 飽受爭議的原則
      • “單一職責原則”的優勢
      • 怎么用?自己看著辦
    • 里氏替換原則
      • 什么是“里氏替換原則”?
      • 關于里氏替換原則
    • 依賴倒置原則
      • 什么是“依賴倒置原則”
      • 關于依賴倒置原則的小故事
      • 依賴倒置,讓專案并駕齊驅
      • 最佳實踐
    • 介面隔離原則
      • 什么是“介面隔離原則”?
      • 介面要高內聚
      • 最佳實踐
    • 迪米特法則
      • 松耦合的法則:迪米特法則
    • 開-閉原則
      • 何為“開閉原則”
      • 如何應對需求變化?

單一職責原則

什么是“單一職責原則”?

如果要理解為:一個類只有一個職責,當然也是可以的,簡單化嘛,
單一職責的原話解釋是這樣的:There should never be more than one reason for a class to change.
什么意思?那里,應該,沒有,多于,一個,原因,使得,類,去,改變,
啊,咱這蹩腳英語,勉強能翻譯啊,

不過,能看懂是一回事,具體實作就是另一個故事了,,,

飽受爭議的原則

為什么飽受爭議呢?看著多單純一原則啊,
這樣,我們來看一個打電話的程序:

class 電話{
public:
void 撥出電話(string 電話號碼);
void 瞎比比(Object *嗶嗶類物件); //總不能傳個string吧,說一句就沒啦?
void 掛電話();
};

這個有沒有問題?是有那么小問題的嘞,
你說我哪天,撥號的方法要改一下,我變成撥不通就一直撥,那這個類變一下,
然后我通信的方法再改一下,我現在不允許兩個人同時說話,一個說完另一個再說,那這個類再變一下,

這個類,有兩個職責:協議管理和資料傳送,

那怎么搞?把那倆介面獨立出來唄,然后將兩個職責融合在一個類中,

在這里插入圖片描述

現在變成了一個類融合了兩個介面,確實那個實作類還是有兩個原因引起變化,但是別忘了,我們是面向介面編程(后面會提到,依賴倒置原則),我們對外公布的是介面,又不是實作類,

如果你非要對這個栗子實作單一原則,也可以,你要有那個權力或精力(因為我估計沒人愿意陪你這樣玩),

“單一職責原則”的優勢

  • 類的復雜性降低,實作什么職責都有明確的定義, 這是最首要的,如果不能降低復雜度,那就別分開
  • 可讀性提高
  • 可維護性提高
  • 變更引起的風險降低

怎么用?自己看著辦

對于介面,我們在實作的時候一定要做到單一,但是對于實作類就需要多方面考慮了,
生搬硬套的話會有什么不良反應,去試試就知道了,

單一職責很難在專案中得到體現,就拿上面那栗子來說,能把介面分開就謝天謝地吧,
當然,單一職責也可以用于類方法,說來慚愧,我曾經用一個類方法實作五個功能(通過巧妙設定引數),,,,
現在想想,真是好笑啊,


里氏替換原則

什么是“里氏替換原則”?

這個原則,說簡單也簡單,說拗口也拗口,

是這樣說的:Function that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有參考基類的地方,必須能透明的使用其子類物件,

什么意思呢?就是子類必須實作父類的所有方法,有父類出現的地方,子類就可以出現,

關于里氏替換原則

關于里氏替換原則,我并不想講太多,無非就是父類弄成純虛基類,然后客端呼叫的時候以子類來new出父類宣告的物件:父類 * 物件 = new 某子類();
這種格式后面會常見,見到的時候自然就明白了,


依賴倒置原則

什么是“依賴倒置原則”

這是我最喜歡的一個原則,也是受益最大的,
它的定義是:High level modules should not depend upon low level modules. Both should depend upon abstractions. Absteactions should not depend upon details.Details should depend upon abstractions.

  • 高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象,
  • 抽象不應該依賴于細節,
  • 細節應該依賴于抽象,

關于依賴倒置原則的小故事

故事是別人的,不過放在這里也是很應景啦,
故事是這樣的:
有個適齡小伙子,他還單著,有一天,他喜歡的那個姑娘突然給他打電話,說她的電腦壞了,一用就藍屏警告,姑娘講著講著就要哭出來了,小伙子那個急啊,他心疼啊,所幸,小伙子憑借高超的技術,當機立斷:記憶體潭訓了,但是又苦于所愛隔山水啊,所以他只能當遠程指揮官了,他指導姑娘:扒開電腦主機后蓋,把記憶體條扯出來,然后開機看看,如果還藍屏,那就把那條記憶體條插回去,把另一條拔出來,一頓操作猛如虎,姑娘在小伙無私又認真的指揮下,把電腦修好了,
過兩天,姑娘又打電話給小伙子,說她收音機壞了,希望小伙能再遠程指導一次,但是這次小伙無能了,他不行了,他不會,太難了,他放棄了,他把電話掛了,姑娘很失望,

但是姑娘不知道,電腦,是松耦合,強內聚的,哪個部件壞了就換哪個,但是收音機不一樣,收音機是緊耦合的,牽一發而動全身,收音機沒聲音,可能是擴音器壞了,可能是信號接收其壞了,可能是解頻罷工了···畢竟她是外行嘛,悲催的小伙子,

那么,就要切入到我們的正題了,松耦合、強內聚的電腦,是怎么組裝的呢?

像記憶體條這種東西啊,管你是哪家生產的,只要符合規格,再比如滑鼠、鍵盤、電池(電池得配套),反正哪個部件壞了就換哪個部件,為什么這些部件不論插在哪一臺電腦上都能使用呢?是這些部件配合電腦主板設計,還是電腦主板配合這些零部件設計呢?

想來答案已經很明確了,就拿CPU來說,CPU的對外都是針腳式或觸點式的標準介面,只要介面設計好,內部再復雜和外界也沒有關系,哪個主板要插CPU,那就得和CPU的介面對上,那么這時候如果電腦的記憶體潭訓了,就不該成為你更換麥克風的理由,這不是開玩笑,要是收音機的外放壞了,可能得整部收音機脫胎換骨了,

PC的介面始終是有限的,但是軟體設計得好,卻可以不斷地拓展的,

依賴倒置,讓專案并駕齊驅

我們來思考一下依賴倒置對并行開發的影響,
如果兩個類之間有依賴關系,只要定制出兩者之間的介面(或抽象類),就可以獨立開發了,就像我最近做的一個圖書管理專案,只要合理地運用依賴倒置,便可以很好的將界面與后臺資料訪問解耦合,從而實作并行開發,

最佳實踐

依賴倒置原則的本質就是通過抽象使得各個類或模塊的實作彼此獨立,不互相影響,實作模塊之間的松耦合,我們怎么在專案中使用這個規則呢?只要通過以下的幾個規則:

  • 每個類盡量都有介面或抽象類,或者抽象和介面二者都具備,
  • 變數的表面型別盡量是介面或者抽象類,
  • 任何類都不應該從具體類派生,
  • 盡量不要覆寫基類的方法,
  • 結合里氏替換原則,

反正我以前是一條都沒對上,

“依賴倒轉原則”在小專案上很難體現出來,


介面隔離原則

什么是“介面隔離原則”?

它建立在“依賴倒置原則”之上,
它的定義有倆:

  • Client should not be forced to depend upon interfaces that they don’t use.
  • 客戶端不應該依賴于它不需要的介面,
  • The dependency of one class to another one should depend on the smallest possible interface.
  • 類之間的依賴關系應該建立在最小的介面上,

簡單易懂啊,如果對前面那個原則有一定的把握,

建立單一介面,介面盡量細化,


介面要高內聚

什么是高內聚?高內聚就是提高介面、類、模塊的處理能力,減少對外的互動,比如說你告訴你的保鏢,今天去給我買一打愛馬仕,他就去了,你也不用問他花了多少錢,他也不用問你是不是抽風了,這種不問條件執行的行為就是高內聚,
介面是對外的承諾,承諾越少對系統的開發越有利,變更的風險也越大,同時也有利于降低成本,

最佳實踐


 - 一個介面只服務于一個子模塊或業務邏輯
 - 通過業務邏輯壓縮介面中的public方法,介面要勤快點重構
 - 已經被污染的介面,盡量去修改
 - 了解環境,拒絕盲從

迪米特法則

松耦合的法則:迪米特法則

英文解釋:Only talk to your immedate friends.
只與直接的朋友通信,

如果兩個類之間不能直接通信,那么這兩個類就不應該發生直接的相互作用,如果其中一個類需要呼叫另一個類的某一個方法的話,可以通過第三者轉發這個呼叫,

迪米特法則首先強調在類的設計上,每一個類都應該盡量降低成員的訪問權限,強調了類之間的松耦合,

類之間的耦合越弱,越有利于重復利用,一個處在弱耦合的類被修改,不會對相關類造成波及,

開-閉原則

何為“開閉原則”

Software entities like classes, modules and functions should be open for extension but closed for modifications.
一個軟體物體,應該對拓展開放,對修改關閉,

抽象物體:

專案或軟體產品中按照一定的邏輯規則劃分的模塊,
抽象類
方法

這個原則很重要,后面會很經常見,
多說無益,我就稍微說兩句,后面慢慢看它真面目,

如何應對需求變化?

既然說,對修改要關閉,那需求變化了怎么辦?
有如下方法:

1、修改介面
2、修改實作類
3、通過拓展實作變化

至于為什么需要這個原則、如何使用、何時使用這個原則,跟著我的步伐,往后看,


今天的分享到此告一段落,算是我回歸設計模式模塊的禮物,

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/257831.html

標籤:其他

上一篇:SpringBoot快速入門---One---搭建環境以及新建專案

下一篇:產品經理的私房菜 排版篇

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more