




已閱讀5頁,還剩14頁未讀, 繼續免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
一、設計模式的六大原則1、開閉原則(Open Close Principle)開閉原則就是說對擴展開放,對修改關閉。在程序需要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。所以一句話概括就是:為了使程序的擴展性好,易于維護和升級。想要達到這樣的效果,我們需要使用接口和抽象類。開閉原則是面向對象的可復用設計的第一塊基石。開閉原則的關鍵是抽象化。2、里氏代換原則(Liskov Substitution Principle)里氏代換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。 里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承復用的基石,只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被復用,而衍生類也能夠在基類的基礎上增加新的行為。里氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關系就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規范。面向對象的設計關注的是對象的行為,它是使用“行為”來對對象進行分類的,只有行為一致的對象才能抽象出一個類來。我經常說類的繼承關系就是一種“Is-A”關系,實際上指的是行為上的“Is-A”關系,可以把它描述為“Act-As”。3、依賴倒轉原則(Dependence Inversion Principle)這個是開閉原則的基礎,具體內容:真對接口編程,依賴于抽象而不依賴于具體。4、接口隔離原則(Interface Segregation Principle)這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實設計模式就是一個軟件的設計思想,從大型軟件架構出發,為了升級和維護方便。所以上文中多次出現:降低依賴,降低耦合。5、迪米特法則(最少知道原則)(Demeter Principle)最少知道原則,就是說:一個實體應當盡量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立。6、合成復用原則(Composite Reuse Principle)合成/聚合復用原則是在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分;新的對象通過向這些對象的委派達到復用已有功能的目的。合成(Composition)和聚合(Aggregation)都是關聯(Association)的特殊種類。原則是盡量使用合成/聚合的方式,而不是使用繼承。11.開閉原則實例Fruit接口:抽象產品Orange類:實現fruit接口,具體產品Apple類:實現Fruit接口,具體產品Gardener接口:抽象工廠AppleGardener類:實現Gardener接口,具體工廠,分管apple生產OrangeGardener類:實現Gardener接口,具體工廠,分管orange生產package com.zky.www.factory;public interface Fruit /水果接口public void plant();public void grow();public void harvest();public class Apple implements Fruit /蘋果實現水果接口public void grow() System.out.println(apple is growing!);public void harvest() System.out.println(apple is harvesting!);public void plant() System.out.println(apple is planting!);public class Orange implements Fruit /桔子實現水果接口public void grow() System.out.println(orange is growing!);public void harvest() System.out.println(orange is harvesting!);public void plant() System.out.println(orange is planting!);public interface Gardener /園丁接口public Fruit getFruit();public class AppleGardener implements Gardener Overridepublic Fruit getFruit() return new Apple();public class OrangeGradener implements Gardener Overridepublic Fruit getFruit() return new Orange();public class Client public static void main(String args) Gardener g1=new AppleGardener();Apple apple=(Apple) g1.getFruit();apple.harvest();22、里氏代換原則實例正方形不是長方形package com.zky.www.liskov;public class Rectangle private double width;private double height;public Rectangle()public Rectangle(double width, double height) super();this.width = width;this.height = height;public double getWidth() return width;public void setWidth(double width) this.width = width;public double getHeight() return height;public void setHeight(double height) this.height = height;package com.zky.www.liskov;public class Square extends Rectangle private double side;public Square(double side) super();this.side = side;public double getSide() return side;public void setSide(double side) this.side = side;package com.zky.www.liskov;public class SmartTest public void resize(Rectangle r)while (r.getHeight()=r.getWidth()r.setWidth(r.getWidth()+1);33、依賴倒轉原則實例publicclassBenz /汽車肯定會跑 publicvoidrun() System.out.println(奔馳汽車開始運行.); publicclassDriver /司機的主要職責就是駕駛汽車 publicvoiddrive(Benz benz) benz.run(); publicclassClient publicstaticvoidmain(String args) Driver zhangSan = newDriver(); Benz benz = newBenz(); /張三開奔馳車 zhangSan.drive(benz); 上面實例,司機張三只能開奔馳車,不能開其他車,因此設計出了問題,改正如下。publicinterfaceIDriver /是司機就應該會駕駛汽車 publicvoiddrive(ICar car); publicclassDriver implementsIDriver /司機的主要職責就是駕駛汽車 publicvoiddrive(ICar car) car.run(); publicinterfaceICar /是汽車就應該能跑 publicvoidrun(); publicclassBenz implementsICar /汽車肯定會跑 publicvoidrun() System.out.println(奔馳汽車開始運行.); publicclassBMW implementsICar /寶馬車當然也可以開動了 publicvoidrun() System.out.println(寶馬汽車開始運行.); 在業務場景中,我們貫徹“抽象不應該依賴細節”,也就是我們認為抽象(ICar接口)不依賴BMW和Benz兩個實現類(細節),因此我們在高層次的模塊中應用都是抽象,Client的實現過程如下:public class Client public static void main(String args) IDriver zhangSan = new Driver();ICar benz = new Benz();/張三開奔馳車zhangSan.drive(benz); Client屬于高層業務邏輯,它對低層模塊的依賴都建立在抽象上,zhangSan的顯示類型是IDriver,benz的顯示類型是ICar,也許你要問,在這個高層模塊中也調用到了低層模塊,比如new Driver()和new Benz()等,如何解釋?確實如此,zhangSan的顯示類型是IDriver,是一個接口,是抽象的,非實體化的,在其后的所有操作中,zhangSan都是以IDriver類型進行操作,屏蔽了細節對抽象的影響。當然,張三如果要開寶馬車,也很容易,我們只要修改業務場景類就可以。注意在Java中,只要定義變量就必然要有類型,一個變量可以有兩個類型:顯示類型和真實類型,顯示類型是在定義的時候賦予的類型,真實類型是對象的類型,如zhangSan的顯示類型是IDriver,真實類型是Driver。44.接口隔離原則public interface IPettyGirl /要有姣好的面孔public void goodLooking();/要有好身材public void niceFigure();/要有氣質public void greatTemperament();public class PettyGirl implements IPettyGirl private String name;/美女都有名字public PettyGirl(String name) this. name=name; /臉蛋漂亮public void goodLooking() System. out.println(this. name + -臉蛋很漂亮!); /氣質要好public void greatTemperament() System. out.println(this. name + -氣質非常好!); /身材要好public void niceFigure() System. out.println(this. name + -身材非常棒!); public abstract class AbstractSearcher protected IPettyGirl pettyGirl;public AbstractSearcher(IPettyGirl _pettyGirl) this.pettyGirl = _pettyGirl; /搜索美女,列出美女信息public abstract void show();public class Searcher extends AbstractSearcherpublic Searcher(IPettyGirl _pettyGirl) super(_pettyGirl); /展示美女的信息public void show() System. out.println(-美女的信息如下: -); /展示面容 super. pettyGirl.goodLooking(); /展示身材super. pettyGirl.niceFigure(); /展示氣質 super. pettyGirl.greatTemperament(); public class Client /搜索并展示美女信息public static void main(String args) /定義一個美女 IPettyGirl yanYan = new PettyGirl(嫣嫣); AbstractSearcher searcher = new Searcher(yanYan); searcher.show(); 如果星探想找有內在氣質的,不找外形漂亮的,怎么辦?看來IPettyGirl接口功能有些臃腫,因此把原 IPettyGirl 接口拆分為兩個接口,一種是外形美的美女 IGoodBodyGirl,這類美女的特點就是臉 蛋和身材極棒,超一流,但是沒有審美素質,比如隨地吐痰,出口就是臟話,文化程度比較低; 另外一種是氣質美的美女 IGreatTemperamentGirl,談吐和修養都非常高。我們從一個比較臃腫的接口拆分 成了兩個專門的接口,靈活性提高了,可維護性也增加了,不管以后是要外形美的美女還是氣質美的美女 都可以輕松的通過 PettyGirl 定義。我們先看兩種類型的美女接口:public interface IGoodBodyGirl /要有姣好的面孔public void goodLooking();/要有好身材public void niceFigure();public interface IGreatTemperamentGirl /要有氣質public void greatTemperament();實現類沒有改變,只是實現類兩個接口,源碼如下:public class PettyGirl implements IGoodBodyGirl,IGreatTemperamentGirl private String name;/美女都有名字public PettyGirl(String _name) this. name=_name; /臉蛋漂亮public void goodLooking() System. out.println(this. name + -臉蛋很漂亮!); /氣質要好public void greatTemperament() System. out.println(this. name + -氣質非常好!); /身材要好public void niceFigure() System. out.println(this. name + -身材非常棒!); 通過這樣的改造以后,不管以后是要氣質美女還是要外形美女,都可以保持接口的穩定。當然你可能 要說了,以后可能審美觀點再發生改變,只有臉蛋好看就是美女,那這個 IGoodBody 接口還是要修改的呀, 確實是,但是設計時有限度的,不能無限的考慮未來的變更情況,否則就會陷入設計的泥潭中而不能自拔。 以上把一個臃腫的接口變更為兩個獨立的接口依賴的原則就是接口隔離原則,讓 AbstractSearcher 依 賴兩個專用的接口比依賴一個綜合的接口要靈活。接口是我們設計時對外提供的契約,通過分散定義多個 接口,可以預防未來變更的擴散,提高系統的靈活性和可維護性。55.迪米特法則如果兩個類不必彼此直接通信,那么這兩個類就不應當發生直接的相互作用。如果其中的一個類需要調用另外一個類的某一個方法,可以通過第三者轉發這個調用。參考下例,Someone、Friend和Stranger三個類。publicclassSomeonepublicvoidoperation1(Friendfriend)Strangerstranger=vide();stranger.operation3();所以Someone和Friend是朋友類(直接通訊的類)。同理,Friend類持有一個Stranger類的私有對象,他們是朋友類:publicclassFriendprivateStrangerstranger=newStranger();publicvoidoperation2()publicStrangerprovide()returnstranger;在這里,Someone類和Stranger類不是朋友類,但Someone類卻通過Friend類知道了Stranger類的存在,這顯然違反迪米特法則。現在,我們對Someone和Friend類進行重構。首先在Friend類里添加一個方法,封裝對Stranger類的操作:publicclassFriendprivateStrangerstranger=newStranger();publicvoidoperation2()publicStrangerprovide()returnstranger;publicvoidforward()stranger.operation3();然后,我們重構Someone的operation1方法,讓其調用新提供的forward方法:publicclassSomeonepublicvoidoperation1(Friendfriend)friend.forward();現在Someone對Stranger的依賴完全通過Friend隔離,這樣的結構已經符合狹義迪米特法則了。仔細觀察上述結構,會發現狹義迪米特法則一個明顯的缺點:會在系統里造出大量的小方法,散落在系統的各個角落。這些方法僅僅是傳遞間接的調用,因此與系統的商務邏輯無關,當設計師試圖從一張類圖看出總體的框架時,這些小的方法會造成迷惑和困擾。遵循迪米特法則會使一個系統的局部設計簡化,因為每一個局部都不會和遠距離的對象有直接關聯。但是,這也會造成系統的不同模塊之間的通信效率降低,也會使系統的不同模塊之間不容易協調。結合依賴倒轉原則,我們對代碼進行如下重構來解決這個問題,首先添加一個抽象的Stranger類,使Someone依賴于抽象的“Stranger”角色,而不是具體實現:publicabstractclassAbstractStrangerabstractvoidoperation3();然后,讓Stranger從該類繼承:publicclassStrangerextendsAbstractStrangerpublicvoidoperation3()隨后,我們重構Someone使其依賴抽象的Stranger角色:publicclassSomeonepublicvoidoperation1(Friendfriend)AbstractStrangerstranger=vide();stranger.operation3();最后,我們重構Friend的provide方法,使其返回抽象角色:publicclassFriendprivateStrangerstranger=newStranger();publicvoidoperation2()publicAbstractStrangerprovide()returnstranger;現在,AbstractStranger成為Someone的朋友類,而Friend類可以隨時替換掉AbstractStranger的實現類,Someone不再需要了解Stranger的內部實現細節。下圖是重構后的UML類圖:在將迪米特法則運用到系統的設計中時,應注意的幾點: 在類的劃分上,應該創建有弱耦合的類; 在類的結構設計上,每一個類都應當盡量降低成員的訪問權限; 在類的設計上,只要有可能,一個類應當設計成不變類; 在對其他類的引用上,一個對象對其它對象的引用應當降到最低; 盡量降低類的訪問權限; 謹慎使用序列化功能; 不要暴露類成員,而應該提供相應的訪問器(屬性)。66、合成復用原則實例(1)聚合用來表示“擁有”關系或者整體與部分的關系。代表部分的對象有可能會被多個代表整體的對象所共享,而且不一定會隨著某個代表整體的對象被銷毀或破壞而被銷毀或破壞,部分的生命周期可以超越整體。例如,班級和學生,當班級刪除后,學生還能存在,學生可以被培訓機構引用。class Student private String sName;class Classes private Student student; public Classes(Student student) this.student=student; (2)合成用來表示一種強得多的“擁有”關系。在一個合成關系里,部分和整體的生命周期是一樣的。一個合成的新對象完全擁有對其組成部分的支配權,包括它們的創建和湮滅等。使用程序語言的術語來說,合成而成的新對象對組成部分的內存分配、內存釋放有絕對的責任。一個合成關系中的成分對象是不能與另一個合成關系共享的。一個成分對象在同一個時間內只能屬于一個合成關系。如果一個合
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025裝修工程合同書范文
- 2025版本的申通快遞運輸合同
- 人教部編版一年級上冊課文 39 明天要遠足教學設計及反思
- 2025年江西省建筑施工企業勞動合同樣本
- 2025教育器材采購合同
- 2025年土地轉讓合同范本
- 2025租房合同修訂范本
- 2025年未簽合同也未購買社保員工想離職能否獲得賠償
- 沙生植物栽培管理指南
- EPC項目承包合同的挑戰與機遇
- 2025世界防治哮喘日知識講座專題課件
- 糧食安全時政試題及答案
- 小學開展常規教育經驗交流活動方案
- 第四單元專題學習《孝親敬老傳承家風》公開課一等獎創新教學設計-(同步教學)統編版語文七年級下冊名師備課系列
- 茂名市生活垃圾焚燒發電項目
- 2025年03月四川成都農業科技中心公開招聘筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 大學英語四級考試2024年6月真題(第1套)翻譯
- 2024年鄭州鐵路職業技術學院單招職業技能測試題庫必考題
- 2025年03月國家機關事務管理局所屬事業單位公開招聘應屆畢業生14人筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 城市交通中的共享出行模式研究
- 全過程工程咨詢投標方案(技術方案)
評論
0/150
提交評論