版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、、設(shè)計(jì)模式的六大原則1、開閉原則(OpenClosePrinciple)開閉原則就是說對擴(kuò)展開放,對修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。所以一句話概括就是:為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。想要達(dá)到這樣的效果,我們需要使用接口和抽象類。開閉原則是面向?qū)ο蟮目蓮?fù)用設(shè)計(jì)的第一塊基石。開閉原則的關(guān)鍵是抽象化。2、里氏代換原則(LiskovSubstitutenPrinciple)里氏代換原則(LiskovSubstitutionPrincipleLSP)面向?qū)ο笤O(shè)計(jì)的基本原則之一。里氏代換原則中說,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。LSP是繼承
2、復(fù)用的基石,只有當(dāng)衍生類可以替換掉基類,軟件單位的功能不受到影響時(shí),基類才能真正被復(fù)用,而衍生類也能夠在基類的基礎(chǔ)上增加新的行為。里氏代換原則是對“開-閉”原則的補(bǔ)充。實(shí)現(xiàn)“開-閉”原則的關(guān)鍵步驟就是抽象化。而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。面向?qū)ο蟮脑O(shè)計(jì)關(guān)注的是對象的行為,它是使用“行為”來對對象進(jìn)行分類的,只有行為一致的對象才能抽象出一個(gè)類來。我經(jīng)常說類的繼承關(guān)系就是一種“Is-A”關(guān)系,實(shí)際上指的是行為上的“Is-A”關(guān)系,可以把它描述為“Act-As”。3、依賴倒轉(zhuǎn)原貝U(DependenceInversionPrinciple
3、)這個(gè)是開閉原則的基礎(chǔ),具體內(nèi)容:真對接口編程,依賴于抽象而不依賴于具體。4、接口隔離原則(InterfaceSegregationPrinciple)這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。還是一個(gè)降低類之間的耦合度的意思,從這兒我們看出,其實(shí)設(shè)計(jì)模式就是一個(gè)軟件的設(shè)計(jì)思想,從大型軟件架構(gòu)出發(fā),為了升級(jí)和維護(hù)方便。所以上文中多次出現(xiàn):降低依賴,降低耦合。5、迪米特法則(最少知道原則)(DemeterPrinciple)最少知道原則,就是說:一個(gè)實(shí)體應(yīng)當(dāng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對獨(dú)立。6合成復(fù)用原則(CompositeReusePrinciple
4、)合成/聚合復(fù)用原則是在一個(gè)新的對象里面使用一些已有的對象,使之成為新對象的一部分;新的對象通過向這些對象的委派達(dá)到復(fù)用已有功能的目的。合成(Composition)和聚合(Aggregation)都是關(guān)聯(lián)(Association)的特殊種類。原則是盡量使用合成/聚合的方式,而不是使用繼承。11.開閉原則實(shí)例Fruit接口:抽象產(chǎn)品Orange類:實(shí)現(xiàn)fruit接口,具體產(chǎn)品Apple類:實(shí)現(xiàn)Fruit接口,具體產(chǎn)品Gardener接口:抽象工廠AppleGardener類:實(shí)現(xiàn)Gardener接口,具體工廠,分管apple生產(chǎn)OrangeGardener類:實(shí)現(xiàn)Gardener接口,具體工廠
5、,分管orange生產(chǎn)packagecom.zky.www.factory;publicinterfaceFruit/水果接口publicvoidplant();publicvoidgrow();publicvoidharvest();publicclassAppleimplementsFruit/蘋果實(shí)現(xiàn)水果接口publicvoidgrow()Systemout.println(appleisgrowing!);publicvoidharvest()Systemout.println(appleisharvesting!);publicvoidplant()Systemout.println
6、(appleisplanting!);publicclassOrangeimplementsFruit/桔子實(shí)現(xiàn)水果接口publicvoidgrow()Systemout.println(orangeisgrowing!);publicvoidharvest()Systemout.println(orangeisharvestng!);publicvoidplant()Systemout.println(orangeisplanting!);publicinterfaceGardener/園丁接口publicFruitgetFruit();publicclassAppleGardenerimp
7、lementsGardenerOverridepublicFruitgetFruit()returnnewApple();publicclassOrangeGradenermplementsGardenerOverridepublicFruitgetFruit()returnnewOrange();publicclassClientpublicstaticvoidmain(Stringargs)Gardenerg1=newAppleGardener();Appleapple=(Apple)g1.getFruit();apple.harvest();22、里氏代換原則實(shí)例正方形不是長方形isko
8、v;publicclassRectangleprivatedoublewidth;privatedoubleheight;publicRectangle()publicRectangle0oublewidth,doubleheight)super();this.width=width;this.height=height;publicdoublegetWidth()returnwidth;publicvoidsetWidth(doublewidth)this.width=width;publicdoublegetHeight()returnheight;publicvoidsetHeight(
9、doubleheight)this.height=height;iskov;publicclassSquareextendsRectangleprivatedoubleside;publicSquaredoubleside)super();this.side=side;publicdoublegetSide()returnside;publicvoidsetSideQoubleside)this.side=side;iskov;publicclassSmartTestpublicvoidresize(Rectangler)while(r.getHeight()v=r.getWidth()r.s
10、etWidth(r.getWidth()+1);33、依賴倒轉(zhuǎn)原則實(shí)例publicclassBenz/汽車肯定會(huì)跑(”奔馳汽車開始運(yùn)行.);publicclassDriver/司機(jī)的主要職責(zé)就是駕駛汽車publicvoiddrive(Benzbenz)benz.run();publicclassClientpublicstaticvoidmain(Stringargs)DriverzhangSan=newDriver();Benzbenz=newBenz();/張三開奔馳車zhangSan.drive(benz);上面實(shí)例,司機(jī)張三只能開奔馳車,不能開其他車,因此設(shè)計(jì)出了問題,改正如下。pub
11、licinterfaceIDriver/是司機(jī)就應(yīng)該會(huì)駕駛汽車publicvoiddrive(ICarcar);publicclassDriverimplementsIDriver/司機(jī)的主要職責(zé)就是駕駛汽車publicvoiddrive(ICarcar)car.run();publicinterfaceICar/是汽車就應(yīng)該能跑publicvoidrun();publicclassBenzimplementsICar/汽車肯定會(huì)跑publicvoidrun()System.out.println(奔馳汽車開始運(yùn)行.);publicclassBMWmplementsICar/寶馬車當(dāng)然也可以開
12、動(dòng)了publicvoidrun()(”寶馬汽車開始運(yùn)行.);在業(yè)務(wù)場景中,我們貫徹“抽象不應(yīng)該依賴細(xì)節(jié)”,也就是我們認(rèn)為抽象(ICar接口)不依賴BMW和Benz兩個(gè)實(shí)現(xiàn)類(細(xì)節(jié)),因此我們在高層次的模塊中應(yīng)用都是抽象,Client的實(shí)現(xiàn)過程如下:publicclassClientpublicstaticvoidmain(Stringargs)IDriverzhangSan=newDriver();ICarbenz=newBenz();/張三開奔馳車zhangSan.drive(benz);Client屬于高層業(yè)務(wù)邏輯,它對低層模塊的依賴都建立在抽象上,zhangSan的顯示類型是IDrive
13、r,benz的顯示類型是ICar,也許你要問,在這個(gè)高層模塊中也調(diào)用到了低層模塊,比如newDriver()和newBenz()等,如何解釋?確實(shí)如此,zhangSan的顯示類型是IDriver,是一個(gè)接口,是抽象的,非實(shí)體化的,在其后的所有操作中,zhangSan都是以IDriver類型進(jìn)行操作,屏蔽了細(xì)節(jié)對抽象的影響。當(dāng)然,張三如果要開寶馬車,也很容易,我們只要修改業(yè)務(wù)場景類就可以。注意在Java中,只要定義變量就必然要有類型,一個(gè)變量可以有兩個(gè)類型:顯示類型和真實(shí)類型,顯示類型是在定義的時(shí)候賦予的類型,真實(shí)類型是對象的類型,如zhangSan的顯示類型是IDriver,真實(shí)類型是Driv
14、er。44.接口隔離原則publicinterfaceIPettyGirl/要有姣好的面孔publicvoidgoodLooking();/要有好身材publicvoidniceFigure();/要有氣質(zhì)publicvoidgreatTemperament();publicclassPettyGirlimplementsIPettyGirlprivateStringname;/美女都有名字publicPettyGirl(Stringname)=name;/臉蛋漂亮publicvoidgoodLooking()System.out.println(+-臉蛋很漂亮!);/氣質(zhì)要好publicvo
15、idgreatTemperament()System.out.println(+-氣質(zhì)非常好!);/身材要好publicvoidniceFigure()System.out.println(+-身材非常棒!);publicabstractclassAbstractSearcherprotectedIPettyGirlpettyGirl;publicAbstractSearcher(IPettyGirl_pettyGirl)this.pettyGirl=_pettyGirl;_/搜索美女,列出美女信息publicabstractvoidshow();publicclassSearcherexte
16、ndsAbstractSearcherpublicSearcher(IPettyGirl_pettyGirl)super(_pettyGirl);/展示美女的信息publicvoidshow()System.out.println(美女的信息如下:);/展示面容super.pettyGirl.goodLooking();/展示身材super.pettyGirl.niceFigure();/展示氣質(zhì)super.pettyGirl.greatTemperament();publicclassClient/搜索并展示美女信息publicstaticvoidmain(Stringargs)/定義一個(gè)美
17、女IPettyGirlyanYan=newPettyGirl(嫣嫣);AbstractSearchersearcher=newSearcher(yanYan);searcher.show();如果星探想找有內(nèi)在氣質(zhì)的,不找外形漂亮的,怎么辦?看來IPettyGirl接口功能有些臃腫,因此把原IPettyGirl接口拆分為兩個(gè)接口,一種是外形美的美女IGoodBodyGirl,這類美女的特點(diǎn)就是臉蛋和身材極棒,超一流,但是沒有審美素質(zhì),比如隨地吐痰,出口就是臟話,文化程度比較低;另外一種是氣質(zhì)美的美女IGreatTemperamentGirl,談吐和修養(yǎng)都非常高。我們從一個(gè)比較臃腫的接口拆分成了
18、兩個(gè)專門的接口,靈活性提高了,可維護(hù)性也增加了,不管以后是要外形美的美女還是氣質(zhì)美的美女都可以輕松的通過PettyGirl定義。我們先看兩種類型的美女接口:publicinterfaceIGoodBodyGirl/要有姣好的面孔publicvoidgoodLooking();/要有好身材publicvoidniceFigure();publicinterfaceIGreatTemperamentGirl/要有氣質(zhì)publicvoidgreatTemperament();實(shí)現(xiàn)類沒有改變,只是實(shí)現(xiàn)類兩個(gè)接口,源碼如下:publicclassPettyGirlimplementsIGoodBodyG
19、irl,IGreatTemperamentGirlprivateStringname;/美女都有名字publicPettyGirl(String_name)=_name;_/臉蛋漂亮publicvoidgoodLooking()System.out.println(+-臉蛋很漂亮!);/氣質(zhì)要好publicvoidgreatTemperament()System.out.println(+-氣質(zhì)非常好!);/身材要好publicvoidniceFigure()System.out.println(+-身材非常棒!);通過這樣的改造以后,不管以后是要?dú)赓|(zhì)美女還是要外形美女,都可以保持接口的穩(wěn)定。
20、當(dāng)然你可能要說了,以后可能審美觀點(diǎn)再發(fā)生改變,只有臉蛋好看就是美女,那這個(gè)IGoodBody接口還是要修改的呀,確實(shí)是,但是設(shè)計(jì)時(shí)有限度的,不能無限的考慮未來的變更情況,否則就會(huì)陷入設(shè)計(jì)的泥潭中而不能自拔。以上把一個(gè)臃腫的接口變更為兩個(gè)獨(dú)立的接口依賴的原則就是接口隔離原貝讓AbstractSearcher依賴兩個(gè)專用的接口比依賴一個(gè)綜合的接口要靈活。接口是我們設(shè)計(jì)時(shí)對外提供的契約,通過分散定義多個(gè)接口,可以預(yù)防未來變更的擴(kuò)散,提高系統(tǒng)的靈活性和可維護(hù)性。55迪米特法則如果兩個(gè)類不必彼此直接通信,那么這兩個(gè)類就不應(yīng)當(dāng)發(fā)生直接的相互作用。如果其中的一個(gè)類需要調(diào)用另外一個(gè)類的某一個(gè)方法,可以通過第三
21、者轉(zhuǎn)發(fā)這個(gè)調(diào)用。參考下例,SomeoneFriend和Stranger三個(gè)類。publicclassSomeoneFriendfriend)Friendfriend)Friendfriend)publicvoidoperation1(Friendfriend)Strangerstranger=vide()stranger.operation3();所以Someone和Friend是朋友類(直接通訊的類)同理,F(xiàn)riend類持有一個(gè)Stranger類的私有對象,他們是朋友類:publicclassFriendprivateStrangerstranger=newStranger()publicv
22、oidoperation2()publicStrangerprovide()returnstranger;在這里,Someone類和Stranger類不是朋友類,但Someone類卻通過Friend類知道了Stranger類的存在,這顯然違反迪米特法則?,F(xiàn)在,我們對Someone和Friend類進(jìn)行重構(gòu)。首先在Friend類里添加一個(gè)方法,封裝對Stranger類的操作:publicclassFriend三privateStrangerstranger=newStranger()publicvoidoperation2()publicStrangerprovide()returnstrange
23、r;publicvoidforward()stranger.operation3();然后,我們重構(gòu)Someone的operation1方法,讓其調(diào)用新提供的forward方法:publicclassSomeone三publicvoidoperation1(Friendfriend)friend.forward();1現(xiàn)在Someone對Stranger的依賴完全通過Friend隔離,這樣的結(jié)構(gòu)已經(jīng)符合狹義迪米特法則了。仔細(xì)觀察上述結(jié)構(gòu),會(huì)發(fā)現(xiàn)狹義迪米特法則一個(gè)明顯的缺點(diǎn):會(huì)在系統(tǒng)里造出大量的小方法,散落在系統(tǒng)的各個(gè)角落。這些方法僅僅是傳遞間接的調(diào)用,因此與系統(tǒng)的商務(wù)邏輯無關(guān),當(dāng)設(shè)計(jì)師試圖從一
24、張類圖看出總體的框架時(shí),這些小的方法會(huì)造成迷惑和困擾。遵循迪米特法則會(huì)使一個(gè)系統(tǒng)的局部設(shè)計(jì)簡化,因?yàn)槊恳粋€(gè)局部都不會(huì)和遠(yuǎn)距離的對象有直接關(guān)聯(lián)。但是,這也會(huì)造成系統(tǒng)的不同模塊之間的通信效率降低,也會(huì)使系統(tǒng)的不同模塊之間不容易協(xié)調(diào)。結(jié)合依賴倒轉(zhuǎn)原則,我們對代碼進(jìn)行如下重構(gòu)來解決這個(gè)問題,首先添加一個(gè)抽象的Stranger類,使Someone依賴于抽象的“Stranger”角色,而不是具體實(shí)現(xiàn):publicabstractclassAbstractStrangerabstractvoidoperation3()然后,讓Stranger從該類繼承:publicclassStrangerextendsA
25、bstractStrangerpublicvoidoperation3()public隨后,我們重構(gòu)Someone使其依賴抽象的Stranger角色:publicclassSomeonepublicvoidoperation1(Friendfriend)AbstractStrangerstranger=vide()stranger.operation3()最后,我們重構(gòu)Friend的provide方法,使其返回抽象角色:publicclassFriend=newStranger()=newStranger()=newStranger()privateStrangerstrangerpublic
26、voidoperation2()=newStranger()publicAbstractStrangerprovide。returnstranger;現(xiàn)在,AbstractStranger成為Someone的朋友類,而Friend類可以隨時(shí)替換掉AbstractStranger的實(shí)現(xiàn)類,Someone不再需要了解Stranger的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。下圖是重構(gòu)后的UML類圖:SonefrienA1+operAtiinl:void-strAbstrctStr辿苣虻+operation?voidtprovide:AbstractstranterLStranger+ap?rfctioid:void在將迪米
27、特法則運(yùn)用到系統(tǒng)的設(shè)計(jì)中時(shí),應(yīng)注意的幾點(diǎn):在類的劃分上,應(yīng)該創(chuàng)建有弱耦合的類;在類的結(jié)構(gòu)設(shè)計(jì)上,每一個(gè)類都應(yīng)當(dāng)盡量降低成員的訪問權(quán)限;在類的設(shè)計(jì)上,只要有可能,一個(gè)類應(yīng)當(dāng)設(shè)計(jì)成不變類;在對其他類的引用上,一個(gè)對象對其它對象的引用應(yīng)當(dāng)降到最低;盡量降低類的訪問權(quán)限;謹(jǐn)慎使用序列化功能;不要暴露類成員,而應(yīng)該提供相應(yīng)的訪問器(屬性)O66、合成復(fù)用原則實(shí)例(1)聚合用來表示“擁有”關(guān)系或者整體與部分的關(guān)系。代表部分的對象有可能會(huì)被多個(gè)代表整體的對象所共享,而且不一定會(huì)隨著某個(gè)代表整體的對象被銷毀或破壞而被銷毀或破壞,部分的生命周期可以超越整體。例如,班級(jí)和學(xué)生,當(dāng)班級(jí)刪除后,學(xué)生還能存在,學(xué)生可以被培訓(xùn)機(jī)構(gòu)引用。classStudentprivateStringsName;classClassesprivateStudentstudent;publicClasses(Studentstudent)this.student=student;(2)合成用來表示一種強(qiáng)得多的“擁有”關(guān)系。在一個(gè)合成關(guān)系里,部分和整體的生命周期是一樣的。一個(gè)合成的新對象完全擁有對其組成部分的支配權(quán),包括它們的創(chuàng)建和湮滅等。使用程序語言的術(shù)語來說,合成而成的新對象對組成部分的內(nèi)存分配、內(nèi)存釋放有絕對的責(zé)任。一個(gè)合成關(guān)系中的成分對象是不能
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年直播帶貨主播面試題及表現(xiàn)技巧含答案
- 2026年產(chǎn)品經(jīng)理產(chǎn)品開發(fā)面試題含答案
- 2026年數(shù)據(jù)分析師時(shí)間序列分析面試題及答案
- 2026年電信AI工程師面試題集
- 2026年成都市青羊區(qū)人民政府蔡橋街道辦事處公開招聘城管執(zhí)法輔助人員的備考題庫及一套參考答案詳解
- 《DBT 100-2024區(qū)域性地震安全性評價(jià)》專題研究報(bào)告深度解讀
- 2026年銀行關(guān)系經(jīng)理崗位技能考試題庫含答案
- 2026年電子商務(wù)運(yùn)營專員面試問題集
- 2026年成華區(qū)人社局公開招聘1名編外人員備考題庫及答案詳解1套
- 2026年鄉(xiāng)村環(huán)境治理員工作考核制度含答案
- 國家開放大學(xué)電大本科《流通概論》復(fù)習(xí)題庫
- 2025-2026學(xué)年統(tǒng)編版二年級(jí)語文上冊期末質(zhì)量檢測卷(含答案)
- 2025年學(xué)法減分試題及答案
- 2025年德州樂陵市市屬國有企業(yè)公開招聘工作人員(6人)參考筆試題庫及答案解析
- 邢臺(tái)課件教學(xué)課件
- 醫(yī)防融合視角下家庭醫(yī)生簽約慢病管理策略
- 2025年新能源市場開發(fā)年度總結(jié)與戰(zhàn)略展望
- 中職歷史期末考試及答案
- 從指南看慢性乙型病毒性肝炎的防治策略
- 江蘇省揚(yáng)州市江都區(qū)2025-2026學(xué)年八年級(jí)第一學(xué)期第二次月考語文答案
- 報(bào)廢機(jī)動(dòng)車拆解有限公司應(yīng)急預(yù)案
評論
0/150
提交評論