12設(shè)計(jì)1班設(shè)計(jì)模式源碼及_第1頁
12設(shè)計(jì)1班設(shè)計(jì)模式源碼及_第2頁
12設(shè)計(jì)1班設(shè)計(jì)模式源碼及_第3頁
12設(shè)計(jì)1班設(shè)計(jì)模式源碼及_第4頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、2014-2015 學(xué)年第二學(xué)期設(shè)計(jì)模式大作業(yè)課題名稱:設(shè)計(jì)模式在 Duck 模擬器設(shè)計(jì)中的應(yīng)用班 級:12 級軟工設(shè)計(jì) 1 班 學(xué) 號:1215115238:成 績:2015 年 6 月 18 日實(shí)驗(yàn)介紹:仔細(xì)閱讀Head設(shè)計(jì)模式中第 12 章前一部分的 Duck 模擬器。設(shè)計(jì)實(shí)現(xiàn)一個(gè)類似的鴨子模擬器,除了原有要求外,在一個(gè) Quacklogist 中統(tǒng)計(jì)通知它的鴨子的個(gè)數(shù),在一個(gè)中統(tǒng)計(jì)像鴨子一樣叫的 bird 的個(gè)數(shù),對二者進(jìn)行比較,給出最終的測試代碼。最棒的模式就是將不同的模式找出來讓他們進(jìn)行交互,越使用模式就回越容易發(fā)現(xiàn)他們一同現(xiàn)身在你的設(shè)計(jì)中。這種多個(gè)設(shè)計(jì)模式攜手合作解決問題的模式就

2、叫做復(fù)合模式。Duck 模擬器是一個(gè)優(yōu)秀的實(shí)驗(yàn)項(xiàng)目,在模擬器中,用到了許多模式,例如:裝飾模式,抽象工廠模式,迭代器模式,適配器模式等等。多種模式協(xié)作完成實(shí)現(xiàn)鴨子的行為,解決各種問題,實(shí)現(xiàn)了符合模式。實(shí)驗(yàn)過程:如果不使用設(shè)計(jì)模式,代碼就不是規(guī)范的,重用性高的優(yōu)秀代碼。不具有進(jìn)一步開發(fā)的價(jià)值與潛力。代碼如下:先實(shí)現(xiàn)一個(gè)鴨子模擬器,這個(gè)鴨子模擬器由 Duck 及其子類的描述,代碼如下:package import public/鴨子net.nyist.duck.serviceimp; net.nyist.duck.service.Quackable;abstract class,鴨鳴器Quacka

3、bleOverridepublicvoid quack()System.out.prln(Kwak);Publicabstractvoid display();MallardDuck(野鴨)類:package import publicnet.nyist.duck.serviceimp; net.nyist.duck.service.Quackable;classMallardDuckextendsQuackable/實(shí)現(xiàn) Quackable 中的方法,綠頭鴨Overridepublicvoid display()System.out.prln(Greenhead.);RedheadDuck(

4、紅頭鴨)類:package net.nyist.duck.serviceimp;importnet.nyist.duck.service.Quackable;publicclassRedheadDuck extendsQuackable/實(shí)現(xiàn)接口,紅頭鴨 Overridepublicvoid display() System.out.prln(Red head.);RubberDuck(橡皮鴨)類:package import publicnet.nyist.duck.serviceimp; net.nyist.duck.service.Quackable;classRubberDuckext

5、endsQuackable/橡皮鴨publicvoidquack() ln(Squeak);System.out.prOverridepublicvoiddiaplay() ln(YellowSystem.out.prhead.);由此可見程序的耦合度很高,如果添加一個(gè)fly 行為就會涉及到修改很多代碼,程序并不具備進(jìn)一步開發(fā)的價(jià)值。因此,不使用設(shè)計(jì)模式的話是很難開發(fā)出一個(gè)優(yōu)秀的程序。在某個(gè)公司里可以編碼、設(shè)計(jì),在另一個(gè)公司里也是可以編碼或者設(shè)計(jì),但是編碼或者設(shè)計(jì)的具體工作可能不同,于是設(shè)計(jì)或者編碼這些行為屬于你的一個(gè)接口行為,而不是你的行為實(shí)現(xiàn),編碼設(shè)計(jì)類完成相應(yīng)公司的編碼或者設(shè)計(jì)實(shí)現(xiàn) IM

6、PLEMENTS.一定要把變化的部分提煉出來,因此能用接口就少用繼承來想一下,每當(dāng)有新的鴨子子類出現(xiàn)或者鴨子新的特性出現(xiàn),你就不得不被迫在Duck 類里添加并在所有子類里檢查可能需要覆蓋和quark().這簡直是無窮盡的惡夢。所以,需要一個(gè)更清晰的方法,讓某些(而不是全部)鴨子類型可飛或可叫。讓鴨子的特性能有更好的擴(kuò)展性。 試著用一下接口的方式怎么樣?把 quack()取出來,放進(jìn) Quackable 接口中,這樣,實(shí)現(xiàn)這個(gè)接口的鴨子都會叫,而不是所有的鴨子都實(shí)現(xiàn)這個(gè)接口。但這個(gè)方法和上面提到的在子類里去實(shí)現(xiàn) quack 一樣笨,如果幾十種都可以飛,你得在幾十個(gè)鴨子里去寫上一樣的quack()

7、如果一旦這個(gè) quack 有所變更,你將不得不找到這幾十個(gè)鴨子去一個(gè)一個(gè)改它們的 quack()方法。你可能有些氣惱了,這樣也不太正確,那樣也不太正確,告訴我怎么樣弄呢?還有沒有更好的辦法了呢?讓先來總結(jié)一下:知道了使用繼承有一些缺失,因?yàn)楦淖凐喿拥男袨闀绊懰蟹N類的鴨子,而這并不恰當(dāng)。Quackable 接口一開始似乎還挺不錯(cuò), 解決了問題( 只有會叫的鴨子才繼承 Quackable) , 但是 Java 的接口不具有實(shí)現(xiàn)代碼, 所以繼承接口無法達(dá)到代碼的復(fù)用。這意味著:無論何時(shí)你需要修改某個(gè)行為, 你必須得往下追蹤并修改每一個(gè)定義此行為的類。根據(jù)策略模式的第一原則:找出應(yīng)用中可能需要變化

8、之處,把它們獨(dú)立出來,不要和那些不需要變化的代碼混在一起。好吧,回頭看一下這個(gè) Duck 類,就目前所知,除了 quack()之外,Duck類還算一切正常,主要是鴨子的行為總是可能變化的,讓那就把這些行為獨(dú)立出來。頭痛就在于這些行為的變化,為了要把這兩個(gè)行為從 Duck 類中分開,把它們自 Duck 類中取出,建立一組新類代表每個(gè)行為。各自 的動(dòng)作。建立類(完全遠(yuǎn)離 Duck 類),是quack相關(guān)的,這一組類將實(shí)現(xiàn)在實(shí)現(xiàn) Duck 模擬器時(shí),要對 Duck 對象進(jìn)行分析,Quack 是所有鴨子都具有的的特性,而且所有鴨子的這些特性都相同,因此,這個(gè)方法可以直接在Duck 類中實(shí)現(xiàn)。但隨著鴨子

9、的種類不同,quack 也有所不同,因此,quack 應(yīng)該是Quackable 中的抽象方法,使用多態(tài)在實(shí)體類DuckCall、MallardDuck、RedheadDuck、 RubberDuck 中實(shí)現(xiàn)接口 Quackable 中的 quack()方法。代碼如下:接口:publicerface Quackable /創(chuàng)建一個(gè)接口,里面有一個(gè)quack方法public void quack();實(shí)體類:public class RubberDuck implements Quackable/橡皮鴨 Overridepublic void quack() System.out.prln(Squ

10、eak);public class MallardDuck implements Quackable/實(shí)現(xiàn)Quackable中的方法,綠頭鴨 Overridepublic void quack() System.out.prln(Quack);以上的實(shí)體類都實(shí)現(xiàn)了Quackable 接口,但是都通過多態(tài)的方式實(shí)現(xiàn)了各自不同的所示:,畫出相應(yīng)的類圖,四個(gè)實(shí)體類實(shí)現(xiàn)了Quackable 接口,如下圖根據(jù)實(shí)際情況,有鴨子出現(xiàn)的地方就可能有鵝出入,鵝會叫,會游泳,和鴨子差不多,因此,也可以將鵝加入模擬器中。創(chuàng)建一個(gè) Goose 類,再創(chuàng)建一個(gè) GooseAdapter 類,作為適配器將鵝利用 Quac

11、kable 實(shí)現(xiàn)自己的,適配器模式(有時(shí)候也稱包裝樣式或者包裝)將一個(gè)類的接口適配成用戶所期待的。一個(gè)適配允許通常因?yàn)榻涌诓患嫒荻荒茉谝黄鸸ぷ鞯念惞ぷ髟谝黄?,做法是將類自己的接口具體代碼如下:鵝:public class Goose public void honk()在一個(gè)已存在的類中。System.out.prln(Honk);鵝適配器:public class GooseAdapter implements QuackableGoose goose;/構(gòu)造器傳入要適配的鵝對象public GooseAdapter(Goose goose)this.goose=goose;Overrid

12、epublic void quack() goose.honk();創(chuàng)建測試類去驗(yàn)證鵝是否隨著鴨子出自己的,代碼及結(jié)果如下:public class Test public sic void main(String args) /創(chuàng)建一個(gè)模擬器,調(diào)用simulate()方法 Test test=new Test(); test.simulate();void simulate()/產(chǎn)生實(shí)例化對象QuackableQuackable Quackable QuackablemallardDuck=new MallardDuck();redheadDuck=new RedheadDuck(); du

13、ckCall=new DuckCall(); rubberDuck=new RubberDuck();/通過把Goose包裝進(jìn)GooseAdapter,就可以讓鵝像鴨子一樣Quackable gooseDuck=new GooseAdapter(new Goose();System.out.pr/重載ln(nDuck Simulator:);simulate(mallardDuck);simulate(redheadDuck); simulate(duckCall); simulate(rubberDuck);/鵝被包裝起來,可以將其當(dāng)做其它鴨子的Quackable對象 simulate(go

14、oseDuck);/利用多態(tài)調(diào)用響應(yīng)的方法void simulate(Quackable duck) duck.quack();Duck 模擬器要求統(tǒng)計(jì)所有的鴨子的叫了幾次,需要?jiǎng)?chuàng)造一個(gè)裝飾者QuackCounter,通過把鴨子包裝進(jìn)裝飾者對象,給鴨子一些新的行為,而不必修改鴨子的代碼 。裝飾模式在不必改變原類文件和使用繼承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對象的功能。它是通過創(chuàng)建一個(gè)包裝對象,也就是裝飾來真實(shí)的對象。利用繼承設(shè)計(jì)子類的行為,是在編譯時(shí)靜態(tài)決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴(kuò)展對象的行為,就可以在運(yùn)行時(shí)動(dòng)態(tài)地進(jìn)行擴(kuò)展。裝飾模式對于繼承來說,更具有靈活

15、性,而且通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創(chuàng)造出很多不為的組合。但是,這種比繼承更加靈活機(jī)動(dòng)的特性,也同時(shí)意味著更加多的復(fù)雜性。裝飾模式會導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小類,如果過度使用,會使程序變得很復(fù)雜。裝飾模式和適配器模式相比,適配器也可以在轉(zhuǎn)換時(shí)增加新的職責(zé),但主要目的不在此。裝飾者模式主要是給被裝飾者增加新的職責(zé)。適配器模式是用新接口來調(diào)用原接口,原接口 對新系統(tǒng)是不可見或者說不可用的。裝飾者模式原封不動(dòng)的使用原接口,系統(tǒng)對裝飾的對象 也通過原接口來完成使用。(增加新接口的裝飾者模式可以認(rèn)為是其變種-“半透明”裝飾者)。適配器是知道被適配者的詳細(xì)情況的(就是那個(gè)類或那個(gè)接口)

16、。裝飾者只知道其接口是什么,至于其具體類型(是基類還是其他派生類)只有在運(yùn)行期間才知道。具體創(chuàng)建如下:public class QuackCounter implements QuackableQuackable duck;/所有呱呱叫次數(shù)sicnumberOfQuacks;public QuackCounter (Quackablethis.duck=duck;Overridepublic void quack() duck.quack(); numberOfQuacks+;duck)public sicgetQuacks()return numberOfQuacks;測試代碼片段:Quac

17、kableQuackable QuackablemallardDuck=new QuackCounter(new MallardDuck();redheadDuck=new QuackCounter(new RedheadDuck(); duckCall=new QuackCounter(new DuckCall();Quackable rubberDuck=new QuackCounter(new RubberDuck();結(jié)果截圖:需要將對象包裝起來,這就需要用到抽象工廠模式。抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式是指當(dāng)有多個(gè)抽象角色時(shí),使用的一種工

18、廠模式。抽象工廠模式可以向客戶 端提供一個(gè)接口,使客戶端在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對象。根據(jù)LSP 原則,任何接受父類型的地方,都應(yīng)當(dāng)能夠接受子類型。因 此,實(shí)際上系統(tǒng)所需要的,僅僅是類型與這些抽象產(chǎn)品角色相同的一些實(shí)例,而不是這些抽象產(chǎn)品的實(shí)例。換言之,也就是這些抽象產(chǎn)品的具體子類的實(shí)例。工廠類 負(fù)責(zé)創(chuàng)建抽象產(chǎn)品的具體子類的實(shí)例。抽象工廠模式分離了具體的類,易于交換產(chǎn)品系列,因此有利于產(chǎn)品的一致性Duck 模擬器中的抽象工廠命名為AbstractDuckFactory ,在 DuckFactory 類中實(shí)現(xiàn)它,并在測試類中調(diào)用,具體的代碼為:public abstr

19、act class AbstractDuckFactory /每個(gè)方法創(chuàng)建一種腰子public abstract Quackable createMallardDuck(); public abstract Quackable createRedheadDuck(); public abstract Quackable createDuckCall(); public abstract Quackable createRubberDuck();public class DuckFactory extends AbstractDuckFactory/每個(gè)方法創(chuàng)建一個(gè)產(chǎn)品,一種特定種類的 Quac

20、kable。模擬器并不知道實(shí)際的產(chǎn)品是什么只知道了它實(shí)現(xiàn)了Quackable 接口Overridepublic Quackable createMallardDuck() return new MallardDuck();Overridepublic Quackable createRedheadDuck() return new RedheadDuck();Overridepublic Quackable createDuckCall() return new DuckCall();Overridepublic Quackable createRubberDuck() return new

21、RubberDuck();抽象工廠的測試代碼為:void simulate(AbstractDuckFactory duckFactory) / 通過類名點(diǎn)調(diào)用方法創(chuàng)建實(shí)例化鴨子,使用工廠調(diào)用QuackableQuackable Quackable QuackablemallardDuck = duckFactory.createMallardDuck();redheadDuck = duckFactory.createRedheadDuck(); duckCall = duckFactory.createDuckCall(); rubberDuck = duckFactory.createR

22、ubberDuck();/ 通過把Goose包裝進(jìn)GooseAdapter,就可以讓鵝像鴨子一樣Quackable gooseDuck = new GooseAdapter(new Goose();System.out.prFactory);/ 重載ln(nDuck Simulator:Wibstractsimulate(mallardDuck);simulate(redheadDuck); simulate(duckCall); simulate(rubberDuck);/ 鵝被包裝起來,可以將其當(dāng)做其它鴨子的Quackable對象simulate(gooseDuck);System.out

23、.prln(The ducks quacked +QuackCounter.getQuacks()+ times);/ 利用多態(tài)調(diào)用響應(yīng)的方法void simulate(Quackable duck) duck.quack();類圖為:程序的運(yùn)行結(jié)果為:程序介紹到此,該實(shí)現(xiàn)的都基本實(shí)現(xiàn)。根據(jù)項(xiàng)目要求,可以統(tǒng)計(jì)出所有發(fā)出的鴨子的個(gè)數(shù)。下面就該添加 Bird 類,Bird 也具有叫這個(gè)行為,因此可以將 Bird 類進(jìn)行適配,使它在 Quackable 接口下發(fā)出自己的,并且統(tǒng)計(jì) bird 的個(gè)數(shù)。由題意知必須要有一個(gè) Bird類來實(shí)例化 Bird 對象,因此接口。Bird 如下所示: public

24、 class Birdpublic void bird() System.out.pr有必要先來創(chuàng)建一個(gè)Bird 類,這個(gè)類不需要實(shí)現(xiàn) Quackableln(bird);創(chuàng)建完Bird 類后需要它在Quackable 下發(fā)出自己的,因此需要?jiǎng)?chuàng)建一個(gè)Birpter 類來對Bird 進(jìn)行適配,此時(shí)Birpter 需要實(shí)現(xiàn)Quackable 接口。代碼如下所示:public class Birpter implements QuackableBirdCounter bird;/構(gòu)造器傳入要適配的鳥對象public Birpter(BirdCounter birdCounter) super();this.bird = birdCounter;Overridepublic void quack() bird.bird();另外,還需要一個(gè) BirdCounter 來統(tǒng)計(jì)Bird 的個(gè)數(shù),主要代碼如下:public class BirdCounter Bird bird;/所有鳥叫的次數(shù)sicnumberOfBird;public BirdCounter(Bird bir

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論