設計思想系列(一)--UML,時序圖和設計模式六大原則詳解

mp.weixin.qq.com/s?src=11&am…

UML和時序圖
spring

統一建模語言(英語:Unified Modeling Language,縮寫 UML)是非專利的第三代建模和規約語言。UML是一種開放的方法,用於說明、可視化、構建和編寫一個正在開發的、面向對象的、軟件密集系統的製品的開放方法。UML展示了一系列最佳工程實踐,這些最佳實踐在對大規模,複雜系統進行建模方面,特別是在軟件架構層次已經被驗證有效。編程

咱們將從下圖,一一進行講解,對UML圖構建有哪些部分組成:
設計模式

類圖:類圖Class diagram經過顯示出系統的類以及這些類之間的關係來表示系統。類圖是靜態的-它們顯示出什麼能夠產生影響但不會告訴你何時產生影響。好比:動物,鳥,鴨,大雁,這些都是類圖。類使用包含類名、屬性(field) 和方法(method) 且帶有分割線的矩形來表示。好比,動物下面有繁殖等方法。架構

那麼屬性/方法名稱前加的加號和減號是什麼意思呢?它們表示了這個屬性或方法的可見性,UML類圖中表示可見性的符號有三種:框架

+ :表示public函數

- :表示private工具

#:表示protected(friendly也納入這類)設計

所以,上圖中的動物類具備2個公有方法和一個屬性。實際上,屬性的完整表示方式是這樣的:orm

可見性 名稱 :類型 [ = 缺省值]cdn

中括號中的內容表示是可選的,好比spring項目中的Controller下面:


類與類之間關係的表示方式,又有哪些組成呢?


1.依賴關係

在UML類圖中,依賴關係用一條帶有箭頭的虛線表示。好比上圖的,動物依賴空氣和水才能生活。


2.繼承關係

繼承關係對應的是extend關鍵字,在UML類圖中用帶空心三角形的直線表示。好比上圖的,鴨繼承鳥,鳥繼承動物。


3.組合關係

組合關係與聚合關係見得最大不一樣在於:這裏的「部分」脫離了「總體」便不復存在。在UML類圖中,組合關係用一個帶實心菱形和箭頭的直線表示,而且箭頭指向的是"部分"。好比上圖中的,鳥是總體,翅膀是部分,翅膀脫離了鳥就不復存在。


4.聚合關係

由上圖咱們能夠看到,UML中聚合關係用帶空心菱形和箭頭的直線表示。聚合關係強調是「總體」包含「部分」,可是「部分」能夠脫離「總體」而單獨存在。好比上圖中,大雁羣包含了大雁,沒有大雁羣,也能夠說是一隻大雁,大雁能夠單獨存在。


5.關聯關係

在UML類圖中單向關聯用一個帶箭頭的直線表示。好比上面的,企鵝下蛋跟氣候有關聯關係,且是單向關聯關係。


6.接口實現關係

這種關係對應implement關鍵字,在UML類圖中用帶空心三角形的虛線表示。好比上圖中的,大雁實現飛翔這個接口功能。

實戰:

IDEA編譯器,能夠自動生成UML圖,以下操做:在具體類中,點擊右鍵,而後選擇Diagrams選項,而後選擇Show Diagrams就能夠了。



時序圖(Sequence Diagram),又名序列圖、循序圖,是一種UML交互圖。它經過描述對象之間發送消息的時間順序顯示多個對象之間的動態協做。咱們在畫時序圖時會涉及7種元素:角色(Actor)、對象(Object)、生命線(LifeLine)、控制焦點(Activation)、消息(Message)、自關聯消息、組合片斷。下圖,來自網上:

實戰:

IDEA編譯器須要安裝,時序圖生成工具:SequenceDiagram。詳細使用文檔,參考:

https://plugins.jetbrains.com/plugin/8286-sequencediagram

操做使用,也是點擊右鍵,選擇SequenceDiagram就能夠了。



02

六大設計模式原則概述

設計模式六大原則

一、開閉原則OCP

開閉原則說的是,對擴展開放、對修改關閉。在程序須要進行擴展的時候,不能去修改原有的代碼,這也是爲了使程序的擴展性更好、易於升級和維護。

二、里氏代換原則LSP

在軟件中將一個基類對象替換成它的子類對象,程序將不會產生任何錯誤和異常,反過來則不成立。若是一個軟件實體使用的是一個子類對象的話,那麼它必定不可以使用基類對象。里氏代換原則的程序表現就是:在程序中儘可能使用基類類型來對對象進行定義,而在運行時再肯定其子類類型,用子類對象來替換父類。

三、控制反轉原則IOC

針對接口編程,依賴於抽象而不依賴於具體

四、接口隔離原則ISP

使用多個隔離的接口,比使用單個接口要好

五、迪米特法則DP

一個實體應當儘可能少地與其餘實體間發生相互做用,使得系統功能模塊相對獨立

六、合成複用原則

儘可能使用組合/聚合的方式,而不是使用繼承

設計中的三個關鍵字

一、抽象化

在衆多事物中提取出共同的、本質性的特徵,捨棄非本質的特徵,就是抽象化。抽象化的過程也是一個剪裁的過程,在抽象時,同於不一樣,取決於從什麼角度上來抽象。抽象的角度取決於分析問題的目的。

二、實現化

抽象類給出的具體實現,就是實現化。

一個類的實例就是這個類的實例化,一個具體子類是它的抽象超類的實例化。

三、解耦

這就比較重要了,平時咱們老說好的代碼應該是"高內聚、低耦合",那麼什麼是耦合呢?

所謂耦合,就是兩個實體的行爲的某種強關聯。而將它們之間的強關聯去掉,就是解耦。解耦是指將抽象化和實現化之間的耦合解開,或者說是將它們之間的強關聯改換成弱關聯。

所謂強關聯,指的是在編譯時期已經肯定的,沒法在運行時期動態改變的關聯;所謂弱關聯,就是能夠動態地肯定而且在運行時期動態改變的關聯。從這個定義看,繼承關係是強關聯,聚合關係是弱關聯。

03

開閉原則/依賴倒置原則/單一職責原則

1.開閉原則

定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉用抽象構建框架,用實現擴展細節。

優勢:提升軟件系統的可複用性及可維護性。

1.1 實戰

代碼結構,以下:

訴說:ICourse是抽象(接口),JavaCourse 和 JavaDiscountCourse 是實現細節。Test是最上層,調用方。


具體代碼參考:


2.依賴倒置原則

定義:高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象,抽象不該該依賴細節;細節應該依賴抽象。

優勢:針對接口編程,不要針對實現編程。

這個原則,相似spring中的依賴注入,service層之間的調用,不依賴實現的細節,只須要把service接口注入進來就行。該案例中,Geely爲低層模塊,該class要調用個課程,不依賴具體的實現,依賴於抽象(ICourse);Test是最上層,調用方。


3.單一職責原則

定義:不要存在多於一個致使類變動的緣由。一個類/接口/方法只負責一項職責。

優勢:下降類的複雜度、提升類的可讀性,提升系統的可維護性、下降變動引發的風險。

缺點:致使類接口很是多,注重度和平衡。好比,能夠事務和非事務的分開;或者吃(不少吃法放在一塊兒),喝(不少喝法放在一塊兒)。


04

接口隔離原則/迪米特原則/里氏替換原則

4.接口隔離原則

定義:用多個專門的接口,而不使用單一的總接口,客戶端不該該依賴它不須要的接口。一個類對一個類的依賴應該創建在最小的接口上;創建單一接口,不要創建龐大臃腫的接口;儘可能細化接口,接口中的方法儘可能少。

由IAnimalAction接口的方法,拆分紅三個不一樣的方法。這個原則跟單一職責原則有點像,可是單一職責講的是職責,而這個注重的是隔離。這個原則缺點也會致使接口和實現暴增,因此也須要注重度和平衡,通常會破壞這個原則。

5.迪米特原則

定義:一個對象應該對其餘對象保持最少的瞭解。又叫最少知道原則。儘可能下降類與類之間的耦合。

優勢:下降類之間的耦合。

Boss想要知道什麼課程或者開課程,不須要本身去作,Boss下個命令給TeamLeader就能夠了,由項目領導者具體實施。

6.里氏替換原則

定義:若是對每個類型爲T1的對象o1,都有類型爲T2的對象o2,使得以T1定義的全部程序p在全部的對象o1都替換成o2時,程序p的行爲沒有發生變化,那麼類型T2是類型T1的子類型。

定義擴展:一個軟件實體若是適用一個父類的話,那必定適用於其子類,全部引用父類的地方必須能透明地使用其子類的對象,子類對象可以替換父類對象,而邏輯不變。

引伸意義:子類能夠擴展父類的功能,但不能改變父類原有的功能。

含義1:子類能夠實現父類的抽象方法,但不能覆蓋父類的非抽象方法;

含義2:子類中能夠增長本身特有的方法;

含義3:當子類的方法重載父類的方法時,方法的前置條件(即方法的輸入/輸出)要比父類方法的輸入參數更寬鬆;

含義4:當子類的方法實現父類的方法時(重寫/重載或實現抽象方法),方法的後置條件(即方法的輸出/返回值)要比父類更嚴格或相等。

注意點:方法入參和繼承關係。

優勢:約束繼承氾濫,開閉原則的一種體現;增強程序的健壯性,同時變動時也能夠作到很是好的兼容性提升程序的維護性、擴展性。下降需求變動時引入的風險。

使用場景:維護舊代碼的時候,可使用這個原則。


總結:

項目中實際運用講究度和平衡,在寫代碼的時候,能夠先思考一下,遵照這些原則。

相關文章
相關標籤/搜索