說明:設計模式(Design Pattern)對于軟件開發(fā),簡單來說,就是軟件開發(fā)的套路,固定模板。在學習設計模式之前,需要首先學習UML(Unified Modeling Language,統(tǒng)一建模語言)和面向?qū)ο笤O計的七大原則。
UML
設計模式在代碼開發(fā)之前,先需要使用設計圖的方式表現(xiàn)出來,UML是生產(chǎn)設計圖的語言,也就是模型語言。UML的結構有視圖(View)、圖(Diagram)、模型元素(Model Element)、通用機制(General Mechanism),這里不做過深的介紹,只介紹類圖和類之間的關系。
類圖(Class Diagram)
結構
一般來說,一個類由三個部分組成:類名、屬性和方法。如下這個類圖:
- 類名:Teacher;
- 屬性:name(String)、age(int,默認值是0)、gender(String);
- 方法:setAge(int age)、getName();
其中,屬性和方法前面的符號,分別表示可見性:公有(public)、私有(private)、受保護(protected)分別用“+”、“-”、“#”來表示,在Java中,還有一種包內(nèi)可見性(package),使用“*”來表示。
對于屬性,在屬性類型后面加 “= xx”,表示此屬性設置默認值為“xx”,表示方式如下:
可見性 名稱:類型 [= 默認值]
對于方法,表示方式如下:
可見性 名稱([參數(shù)列表])[:返回類型]
以上方括號中的部分,表示可有可無;
如果該類是一個接口,類圖表示如下:
其他內(nèi)容不變,類名上面加兩個尖括號包裹的interface,也有在類名左上角使用一個類似圓形取卡針標志來表示的,如下:
類之間關系
類與類之間的關系,分為以下幾種:
關聯(lián)關系
關聯(lián),指類與類之間存在聯(lián)系,可分為雙向關聯(lián)、單向關聯(lián)、自關聯(lián)、多重性關聯(lián)、聚合和組合,如下:
如下,表示一個按鈕(Button)只能屬于一個表單(Form),是一對一的關系,而一個表單,可以有0個或多個按鈕;
常見的多重性關系有:1…1(一對一)、0…* (0對多) 、1…*(1對多)、0…1(0對一)、m…n(多對多);
例如,汽車(Car)與發(fā)動機(Engine),發(fā)動機是汽車的組成部分,可以獨立于汽車存在,并不依賴于汽車;
例如,頭(Head)與眼睛(Eye),眼睛是頭的組成部分,但是眼睛不能單獨出來,頭沒有了眼睛也就沒有了;
依賴關系;
例如,駕駛員(Driver)與車(Car)的關系,駕駛員依賴于車,沒有車就無法使用駕駛方法;
泛化關系;
泛化關系,就是繼承關系,如下,學生類(Student)和教師類(Teacher)繼承于人類(Person);
實現(xiàn)關系;
實現(xiàn)關系,顧名思義,如下,船(Ship)與車(Car)實現(xiàn)于交通工具接口(Vehicle),并實現(xiàn)其移動方法(move);
其他
實際上,UML的圖遠不止這些,還有用例圖(Use Case Diagram)、對象圖(Object Diagram)、包圖(Package Diagram)等加上類圖共13個,但是類圖用的最多。
在我手邊的《設計模式》(第二版,清華大學出版社,第5頁,劉偉主編)中,作者引用了Martin Fowler著作中的一段話,“If someone were to come up to you in a dark alley and say, ‘Psst, wanna see a UML diagram?’ that diagram would probably be a class diagram.The majority of UML diagrams I see are class diagrams.”(“如果有人在黑暗的小巷中向你走來并對你說:'嘿,想不想看一張UML圖?'那么這張圖很有可能就是一張類圖,我所見過的大部分的UML圖都是類圖”)
面向?qū)ο笤O計原則
面相對象設計原則,指在程序設計時遵循的規(guī)范,有以下七個:
單一職責原則(Single Responsibility Principle,SRP)
單一職責原則定義:一個對象應該只包含單一的職責,并且該職責被完整地封裝在一個類中。
簡單來說,就是一個類,應該只干一件事。例如在沒有三層架構前,一個請求,從接收、分析、處理,都在一個類里完成,無論這個請求的哪一個環(huán)節(jié)發(fā)生了改變都需要修改代碼,可維護性差,代碼耦合高。
開閉原則(Open-Closed Principle,OCP)
開閉原則定義:一個軟件實體應當對擴展開發(fā),對修改關閉。
就是說,后面如果需要新增需求,可以在不修改源碼的基礎上,對系統(tǒng)擴展。舉個例子,一個管理系統(tǒng)的界面,有許多的記錄,許多篩選項,最開始記錄的字段少,篩選項也少,后面字段越來越多,需要新增一些篩選條件。
不符合開閉原則的做法:對DTO對象不斷地新增篩選項,name(姓名)、age(年齡)、createTime(創(chuàng)建時間)……;
符合開閉原則的做法:在DTO對象里定義一個Map對象conditions,用于接收前端傳遞的條件參數(shù)。這樣無論后面新增多少個篩選條件,實體類都不需要修改,只需要在Mapper.xml里面新增篩選字段(conditions.字段名)的查詢條件即可;
private Map<String, String> conditions;
里氏代換原則(Liskov Substitution Principle,LSP)
里氏代換原則可以通俗表述為:在軟件中如果能夠使用基類(父類)對象(的地方),那么一定能夠使用其子類對象。
依賴倒轉(zhuǎn)原則(Dependency Inversion Principle,DIP)
依賴倒轉(zhuǎn)原則定義:高層模塊不應該依賴底層模塊,他們都應該依賴抽象。抽象不應該依賴細節(jié),細節(jié)應該依賴于抽象。
接口隔離原則(Interface Segregation Principle,ISP)
接口隔離原則定義:客戶端不應該依賴那些它不需要的接口。
就是說,對于接口應該盡可能細化,而不是把一堆接口放到到一個大接口里面。如接口A表示飛行,接口B表示跳躍,接口C表示鳴叫,雖然這三個特性麻雀完全符合,但是不能把這三個接口合并到一個接口D中,然后讓麻雀來實現(xiàn),而是應該隔離開,讓具備某種能力的類實現(xiàn)指定的接口。
合成復用原則(Composite Reuse Principle,CRP)
合成復用原則定義:盡量使用對象組合,而不是繼承來達到復用的目的。
簡單來說,就是類之間的關系,少用繼承,盡量使用接口實現(xiàn)或者依賴注入的方式。例如有一個面試題,如何解決ArrayList線程不安全的問題,我所知道的有以下5個方法:
(1)使用CopyOnWriteArrayList();
(2)使用Collections.synchronizedList();
(3)定義一個類MyArrayList,繼承ArrayList,重寫其方法,每個方法用synchronized修飾;
(4)定義一個類MyArrayList,類里面定義一個ArrayList,自定義List的增刪改查方法,用synchronized修飾,方法里面調(diào)用ArrayList對應的方法;
(5)使用Vector;
重點是第三個、第四個方法的對比,前者是繼承,需要重寫父類的方法,后者是設值注入,調(diào)用ArrayList的方法,顯然后者更加靈活。
迪米特法則(Law of Demeter,LoD)
迪米特法則,又稱最少知識原則原則,簡單來說,就是指一個軟件實體應當盡可能少地與其他實體發(fā)生相互作用。這樣,當一個模塊修改時,就會盡量少地影響其他的模塊。文章來源:http://www.zghlxwxcb.cn/news/detail-723219.html
總結
本篇文章內(nèi)容基本來自《設計模式》(第2版,清華大學出版社,劉偉主編)第1、2章文章來源地址http://www.zghlxwxcb.cn/news/detail-723219.html
到了這里,關于【設計模式-1】UML和設計原則的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!