版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
六大設計原則——設計模式之禪秦小波Contents單一職責原則1里氏替換原則2依賴倒置原則3接口隔離原則4迪米特法則5開閉原則6單一職責原則單一職責原則(SingleResponsibilityPrinciple,SRP):Thereshouldneverbemorethanonereasonforaclasstochange.應該有且僅有一個原因引起類的變更
基于角色的訪問控制:用戶管理修改用戶信息信息增加機構(gòu)(一個人屬于多個機構(gòu))增加角色設計問題用戶的屬性和行為沒有分開收集和反饋用戶信息完成用戶信息的維護和變更為什么要把一個接口拆分成兩個呢?——單一職責原則在實際的使用中,更傾向于使用兩個不用的類或接口,如右圖所示:單一職責原則舉例單一職責原則Iphone這個接口有兩個職責:一個是協(xié)議管理,一個是數(shù)據(jù)傳送;其中diag()和huangup()兩個方法實現(xiàn)的是協(xié)議管理,撥號接通和關閉;Chat()和answer()是數(shù)據(jù)的傳送,把說的話轉(zhuǎn)換成模擬信號或者是數(shù)字信號傳遞到對方,然后再把對方傳遞的信號轉(zhuǎn)換。問題:1.兩個職責都能引起類的變化嗎?2.兩個變化會相互影響嗎?這個Iphone接口包含了兩個職責,而且這兩個職責的變化不相互影響,那就考慮拆開成兩個接口。單一職責原則單一職責原則的優(yōu)點:類的復雜性降低:實現(xiàn)什么職責都有清晰明確的定義;可讀性提高:復雜性降低,可讀性就會提高;可維護性提高變更引起的風險降低:變更是必不可少的,接口的單一職責做好的話,一個接口修改只對相應的類有影響,與其他接口無影響,這對項目有非常大的幫助對于接口,設計時要做到單一,但是對于實現(xiàn)類就要多方考慮了,硬套單一職責原則會引起類的劇增,給維護帶來非常多的麻煩,過分的細分類也人為的制造系統(tǒng)的負擔。繼承機制的優(yōu)缺點在面向?qū)ο蟮恼Z言中,繼承是必不可少的、非常優(yōu)秀的語言機制,它有如下優(yōu)點:代碼共享,減少創(chuàng)建類的工作量,每個子類都擁有父類的方法和屬性;提高代碼的重用性;子類可以形似父類,但又異于父類;提高代碼的可擴展性;提高產(chǎn)品或項目的開放性。自然界的所有事物都是有點和缺點并存的,繼承的缺點如下:繼承是侵入性的。只要繼承,就必須擁有父類的所有屬性和方法;降低了代碼的靈活性。子類必須擁有父類的屬性和方法,讓子類自由的世界中多了些約束;增強了耦合性。當父類的常量、變量和方法被修改時,必須要考慮子類的修改,而且在缺乏規(guī)范的環(huán)境下,這種修改可能帶來非常糟糕的結(jié)果——大片的代碼需要重構(gòu)。繼承機制的優(yōu)缺點里氏替換原則問題:怎樣才能讓繼承機制的“利”大于“弊”?引入里氏替換原則里氏替換原則最正宗的定義:Ifforeachobjecto1oftypeSthereisanobjecto2oftypeTsuchthatforallprogramsPdefinedintermsofT,thebehaviorofPisunchangedwheno1issubstitutedforo2thenSisasubtypeofT.(如果對每一個類型為S的對象o1,都有類型為T的對象o2,使得以T定義的所有程序P在所有的對象o1都代換成o2時,程序P的行為沒有發(fā)生變化,那么類型S是類型T的子類型。)里氏替換原則通俗講,只要父類出現(xiàn)的地方子類就可以出現(xiàn),而且替換為子類也不會產(chǎn)生任何錯誤或異常,使用者可能根本就不需要知道是父類還是子類。但是反過來就不行了,有子類出現(xiàn)的地方,父類未必就能適應。1、子類完全繼承父類的方法代碼清單場景類源碼Publicclassclient{Publicstaticvoidmain(string[]args){//產(chǎn)生三毛這個士兵SoldiersanMao=newSoldier();//給三毛一支槍sanMao.setGun(newRifle());sanMao.killEnemy();}}結(jié)果:士兵開始殺敵人…步槍射擊…注意:在類中調(diào)用其他類時務必要使用父類或接口,如果不能使用父類或接口,則說明類的設計已經(jīng)違背了LSP原則。問:如果有一個玩具槍呢?里氏替換原則玩具槍不能殺敵,射不出子彈,在這種情況下,我們發(fā)現(xiàn)業(yè)務調(diào)用類已經(jīng)出現(xiàn)了問題,正常的業(yè)務邏輯已經(jīng)不能運行,怎么辦?兩種解決辦法:在Soldier類中增加instanceof的判斷,如果是玩具槍,就不用來殺敵人。這個方法可以解決問題,但是要知道,在程序中,每增加一個類,所有與這個父類有關的類都必須修改,可行嗎?ToyGun脫離繼承,建立一個獨立的父類,為了實現(xiàn)代碼復用,可以與AbastractGun建立關聯(lián)委托關系。如下圖里氏替換原則注意:如果子類不能完整地實現(xiàn)父類的方法,或者父類的某些方法在子類中已經(jīng)發(fā)生“畸變”,則建議斷開父子繼承關系,采用依賴、聚集、組合等關系代替繼承。2、子類可以有自己的個性子類當然可以有自己的行為和外觀了,也就是方法和屬性,那這里為什么要再提呢?是因為里氏替換原則可以正著用,但是不能反過來用。在子類出現(xiàn)的地方,父類未必就可以勝任。在這里,系統(tǒng)直接調(diào)用了子類,狙擊手是很依賴槍支的,別說換一個型號的槍了,就是換一個同型號的槍也會影響射擊,所以這里就直接把子類傳遞了進來。這個時候,我們能不能直接使用父類傳遞進來呢?里氏替換原則3、覆蓋或?qū)崿F(xiàn)父類的方法時輸入?yún)?shù)可以被放大4、復寫或?qū)崿F(xiàn)父類的方法時輸出結(jié)果可以被縮小依賴倒置原則依賴倒置原則(DependenceInversionPrinciple,DIP):Highlevelmodulesshouldnotdependuponlowlevelmodules.Bothshoulddependuponabstractions.Abstractionsshouldnotdependupondetails.Detailsshoulddependuponabstractions.依賴倒置原則依賴倒置原則包含三層含義:高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節(jié);細節(jié)應該依賴抽象。在java語言中,抽象就是指接口或抽象類,兩者都是不能直接被實例化的;細節(jié)就是實現(xiàn)類,實現(xiàn)接口或繼承抽象類而產(chǎn)生的類就是細節(jié),其特點就是可以直接被實例化,也就是可以加上一個關鍵字new產(chǎn)生一個對象。依賴倒置原則依賴倒置原則在java語言中的表現(xiàn)就是:模塊間的依賴通過抽象發(fā)生,實現(xiàn)類之間不發(fā)生直接的依賴關系,其依賴關系是通過接口或抽象類產(chǎn)生的;接口或抽象類不依賴于實現(xiàn)類;實現(xiàn)類依賴接口或抽象類。采用依賴倒置原則可以減少類間的耦合性,提高系統(tǒng)的穩(wěn)定性,降低并行開發(fā)引起的風險,提高代碼的可讀性和可維護性。注意:設計是否具備穩(wěn)定性,只要適當?shù)亍八伤赏痢保^察“設計的藍圖”是否還可以茁壯地成長就可以得出結(jié)論,穩(wěn)定性較高的設計,在周圍環(huán)境頻繁變化的時候,依然可以做到“我自巋然不動”。在20世紀90年代“個人英雄主義”編程模式還是比較適用的,一個人完成所有的代碼工作。但在現(xiàn)在的大中型項目中已經(jīng)完全不能勝任了,一個項目是一個團隊協(xié)作的結(jié)果,一個“英雄”再厲害也不可能了解所有的業(yè)務和所有的技術,要協(xié)作就要并行開發(fā),要并行開發(fā)就要解決模塊之間的項目依賴關系,那么就需要依賴倒置原則。在業(yè)務場景中,我們貫徹“抽象不應該依賴細節(jié)”,也就是我們認為抽象(ICar接口)不依賴BMW和Benz兩個實現(xiàn)類(細節(jié)),因此在高層次的模塊中應用都是抽象。Client屬于高層業(yè)務邏輯,它對低層模塊的依賴都建立在抽象上,zhangSan的表面類型是IDriver,Benz的表面類型是ICar,是一個接口,是抽象的、非實體化的,在其后的所有操作中,zhangSan都是以IDriver類型進行操作,屏蔽了細節(jié)對抽象的影響。當然,張三如果要開寶馬車,也很容易,我們只要修改業(yè)務場景類就可以實現(xiàn)。在增加低層模塊時,只修改了業(yè)務場景類,也就是高層模塊,對其他低層模塊如Driver類不需要做任何修改,業(yè)務就可以運行,把“變更”引起的風險擴散降低到最小。注意:在java中,只要定義變量就必然要有類型,一個變量可以有兩種類型:表面類型和實際類型,表面類型是在定義的時候賦予的類型,實際類型是對象的類型,如zhangSan的表面類型是IDriver,實際類型是Driver。我們再來思考依賴倒置對并行開發(fā)的影響。兩個類之間有依賴關系,只要制定出兩者之間的接口(或抽象類)就可以獨立開發(fā)了。依賴的三種寫法依賴是可以傳遞的,A對象依賴B對象,B又依賴C,C又依賴D……生生不息,依賴不止,記住一點:只要做到抽象依賴,即使是多層的依賴傳遞也無所畏懼!對象的依賴關系有三種方式來傳遞,構(gòu)造函數(shù)傳遞依賴對象Setter方法傳遞依賴對象接口聲明依賴對象1.構(gòu)造函數(shù)傳遞依賴對象在類中通過構(gòu)造函數(shù)聲明依賴對象,按照依賴注入的說法,這種方式叫做構(gòu)造函數(shù)注入,按照這種方式的注入,IDriver和Driver的程序修改后代碼如下:2.Setter方法傳遞依賴對象在抽象中設置Setter方法聲明依賴關系,依照依賴注入的說法,這事Setter依賴注入,按照這種方式的注入,IDriver和Driver的程序修改后代碼如下:3.接口聲明依賴對象在接口的方法中聲明依賴對象,代碼清單3-6就是采用了接口聲明依賴的方式,該方法也叫做接口注入。依賴倒置原則優(yōu)點依賴倒置原則的優(yōu)點在小型項目中很難體現(xiàn)出來,但是在一個大中型項目中,采用依賴倒置原則有非常多的優(yōu)點,特別是規(guī)避一些非技術因素引起的問題。項目越大,需求變化的概率也越大,通過采用依賴倒置原則設計的接口或抽象類對實現(xiàn)類進行約束,可以減少需求變化引起的工作量劇增的情況。人員變動在大中型項目的維護周期一般都很長,采用依賴倒置原則可以讓維護人員輕松地擴展和維護。依賴倒置原則與開閉原則依賴倒置原則是6個原則中最難以實現(xiàn)的原則,它是實現(xiàn)開閉原則的重要途徑,依賴倒置原則沒有實現(xiàn),就別想實現(xiàn)對擴展開放,對修改關閉。在項目中,大家只要記住是“面向接口編程”就基本上抓住了依賴倒置原則的核心。接口隔離原則接口隔離原則定義:客戶端不應該依賴它不需要的接口;類間的依賴關系應該建立在最小的接口上。建立單一接口,不要建立臃腫龐大的接口,接口盡量細化,同時接口中的方法盡量少。它要求“盡量使用多個專門的接口”。專門接口指提供給每個模塊的都應該是單一接口,提供給幾個模塊就應該有幾個接口,而不是建立一個龐大的臃腫接口,容納所有的客戶端訪問。美女何其多,觀點各不同問題與改進思考一下IPettyGirl這個接口,這個接口是否做到了最優(yōu)化設計?接口IPettyGirl的設計是有缺陷的,過于龐大了,容納了一些可變的因素,根據(jù)接口隔離原則,星探AbstractSearcher應該依賴于具有部分特質(zhì)的女孩子,而我們卻把這些特質(zhì)都封裝了起來,放到了一個接口中,封裝過度了!以上把一個臃腫的接口變更為兩個獨立的接口所依賴的原則就是接口隔離原則,讓星探AbstractSearcher依賴兩個專用的接口比依賴一個綜合的接口要靈活。接口是我們設計時對外提供的契約,通過分散定義多個接口,可以預防未來變更的擴散,提高系統(tǒng)的靈活性和可維護性。接口隔離原則包含以下4層含義:接口要盡量?。骸靶 笔怯上薅鹊?,首先就是不能違反單一職責原則。接口要高內(nèi)聚:要求在接口中盡量少公布public方法,接口是對外的承諾,承諾越少對系統(tǒng)的開發(fā)越有利,變更的風險也就越少,同時也有利于降低成本。定制服務:定制服務就是單獨為一個個體提供優(yōu)良的服務。接口設計是有限度地迪米特法則迪米特法則的定義:迪米特法則(LawofDemeter,LoD)也稱為最少知識原則,一個對象應該對其他對象有最少的了解。一個類應該對自己需要耦合或調(diào)用的類知道得最少,被耦合或調(diào)用的類的內(nèi)部如何復雜都和我沒有關系,那是你的事情,我就知道你提供的這么多public方法,我就調(diào)用這么多,其他的我一概不關心。迪米特法則對類的低耦合提出了明確的要求:1.只和朋友交流朋友類:出現(xiàn)在成員變量、方法的輸入輸出參數(shù)中的類稱為成員朋友類,而出現(xiàn)在方法體內(nèi)部的類不屬于朋友類。注意:一個類只和朋友交流,不與陌生類交流,不要出現(xiàn)getA().getB().GetC().getD()這種情況,類與類之間的關系是建立在類間的,而不是方法見,因此一個方法盡量不引入一個類中不存在的對象,當然,JDKAPI提供的類除外。2.朋友間也是有距離的朋友
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《證券交易概論》課件
- 《信號的描述和分類》課件
- 酒渣鼻樣結(jié)核疹的臨床護理
- 選擇性lgA缺乏癥的臨床護理
- 單純性外陰炎的健康宣教
- 《機床電氣線路的安裝與調(diào)試》課件-第9章
- 奶稀的健康宣教
- 孕期抗磷脂抗體綜合征的健康宣教
- 子宮壁妊娠的健康宣教
- 小腿皮炎的臨床護理
- 教科版2022-2023學年度上學期三年級科學上冊期末測試卷及答案(含八套題)
- 人力資源許可證制度(服務流程、服務協(xié)議、收費標準、信息發(fā)布審查和投訴處理)
- 國家開放大學電大《11662會計信息系統(tǒng)(本)》期末終考題庫及標準參考答案
- DZ/T 0430-2023 固體礦產(chǎn)資源儲量核實報告編寫規(guī)范(正式版)
- 浙西南紅軍歌曲賞析智慧樹知到期末考試答案章節(jié)答案2024年麗水學院
- 教科版小學科學二年級上冊教案(全冊)教學設計
- 2024年考研管理類聯(lián)考綜合能力真題及答案
- 外事實務知到章節(jié)答案智慧樹2023年山東外事職業(yè)大學
- 滿腹經(jīng)綸完整版臺詞
- 9876加幾的進位加法
- 新奧60萬噸甲醇精餾塔內(nèi)件和填料技術(天久)
評論
0/150
提交評論