資源描述:
《奇幻RPG(物品鍛造 與 Decorator模式).docx》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、引言物品鍛造是各類奇幻游戲中的常見(jiàn)功能,就拿眾所周知的Diablo來(lái)說(shuō)吧。假設(shè)角色擁有一把單手劍,可能基礎(chǔ)攻擊力只有13,但是它有三個(gè)裝備孔。當(dāng)給劍鑲嵌一顆藍(lán)寶石的時(shí)候,它就擁有了額外的冰凍效果并多加2點(diǎn)攻擊力;當(dāng)給劍鑲嵌一顆紅寶石的時(shí)候,它又擁有了額外的火焰?zhèn)Σ⒍嗉?點(diǎn)攻擊力;當(dāng)給劍鑲嵌一顆綠寶石的時(shí)候,它又擁有了額外的中毒傷害并多加的4點(diǎn)攻擊力。當(dāng)然,也可以三個(gè)孔都鑲嵌同一色的寶石。本文將說(shuō)明如何使用Decorator模式來(lái)完成這樣的設(shè)計(jì)。使用繼承來(lái)擴(kuò)展我們首先想到應(yīng)該有個(gè)基類Weapon,它供所有各式各樣的武器繼承,比如說(shuō)Sword、Axe、Bow。Description字段代表
2、武器的說(shuō)明,比如“One-HandlightSword”,Damage()方法則用于獲取武器的傷害,GetDescription用于獲取武器的說(shuō)明。在不考慮寶石的情況下,我們得到下面的設(shè)計(jì):現(xiàn)在我們考慮如何創(chuàng)建鑲嵌有寶石的武器。我們首先考慮到可以用繼承來(lái)實(shí)現(xiàn)這樣的設(shè)計(jì),結(jié)果卻發(fā)現(xiàn)如果我們需要定義所有嵌寶石的劍(Sword),就需要3+6+7=16個(gè)類(NOTE:三個(gè)物品孔,每個(gè)孔都有藍(lán)、紅、綠三種選擇,可以兩個(gè)或者三個(gè)孔同一色),如果我們給鑲嵌了兩顆藍(lán)一顆紅寶石的劍命名為Blue2RedSword,給三色不同不劍命名為BlueRedGreenSword,其余的類推。那么,我們會(huì)得到下面這
3、樣龐大的類體系(只繪制了部分):而這僅僅是開(kāi)始,如果我們需要再添一種寶石,比如說(shuō)白色,它可以附加詛咒的效果;或者我們需要給武器再添加一個(gè)物品孔,那么我們的類的數(shù)目將迅速的由十幾個(gè)變成幾十個(gè)。我們發(fā)現(xiàn)使用繼承的問(wèn)題:使用繼承時(shí)將會(huì)創(chuàng)建出大量的類。除此以外,使用繼承,也意味我們需要實(shí)例化一個(gè)特定的子類以獲取我們需要的功能(方法),這在編譯階段(compiletime)就已經(jīng)確定,類的客戶端不能控制何時(shí)(runtime)根據(jù)需要改變,除非再實(shí)例化另一個(gè)子類。使用復(fù)合來(lái)擴(kuò)展我們發(fā)現(xiàn)繼承會(huì)帶來(lái)兩個(gè)主要的問(wèn)題,所以我們考慮換一種方式來(lái)思考,我們可以使用復(fù)合來(lái)完成它。說(shuō)詳細(xì)一點(diǎn),就是我們將藍(lán)寶石(Bl
4、ueDiamond)、紅寶石(RedDiamond)、綠寶石(GreenDiamond)作為實(shí)體變量(instancevariable)復(fù)合到基類中,然后在基類的Damage()方法中計(jì)算出所有寶石額外增加的傷害(此時(shí)基類的Damage()方法不再是抽象的)。publicabstractclassWeapon{???publicvirturlintDamage(){??????inttotal=0;??????if(redDiamond!=null)??????????total+=redDiamond.Damage();??????//附加紅寶石的傷害??????if(blueDiam
5、ond!=null)??????????total+=blueDiamond.Damage();?????//附加藍(lán)寶石的傷害??????if(greenDiamond!=null)??????????total+=greenDiamond.Damage();????//附加綠寶石的傷害??????returntotal;???}}而在實(shí)體子類中,我們覆蓋這個(gè)方法,在方法內(nèi)部先調(diào)用基類方法獲取寶石的附加傷害,然后再給它加上武器本身的傷害。publicclassSword:Weapon{???publicoverrideindDamage(){??????returnbase.Damage
6、()+15;//15是劍本身傷害???}}此時(shí)的圖應(yīng)該變成這樣:相對(duì)于繼承,復(fù)合看上去要好得多,它的類的數(shù)目要少的多,并且又可以在運(yùn)行時(shí)決定是否給武器鑲嵌寶石,但是使用復(fù)合仍存在問(wèn)題:·寶石與劍是緊密耦合在一起的,當(dāng)我們想要為武器添加一個(gè)白寶石,那么我們需要給Weapon基類再添加一個(gè)BlueDiamond字段,同時(shí)還需要修改基類的Damage()方法。簡(jiǎn)言之,每次維護(hù)我們都要修改以前的代碼。1.我們遺忘了一種組合,應(yīng)該記得,我們的劍是可以鑲嵌三個(gè)同色寶石的,比如說(shuō):三個(gè)藍(lán)寶石或者三個(gè)紅寶石,那么上面的設(shè)計(jì)顯然無(wú)法完成。當(dāng)然,我們可以從三種寶石中抽象出一個(gè)Diamond基類來(lái),而在Wea
7、pon中添加三個(gè)Diamond類型的變量。但是,問(wèn)題依然存在:如果我們需要多添一個(gè)裝備孔,那么我們又得再次修改Weapon類。為對(duì)象添加狀態(tài)和行為現(xiàn)在假設(shè)我們不是一名軟件設(shè)計(jì)者,而是一個(gè)游戲玩家,我們要為劍添加一枚紅寶石,一枚藍(lán)寶石,那么實(shí)際的操作順序是什么呢?1.我們當(dāng)然首先要有一把劍。(需要先創(chuàng)建一個(gè)Sword對(duì)象,它只是把劍,不含任何寶石)。1.我們?yōu)閯μ砑右粋€(gè)紅寶石。(我們包裝Sword對(duì)象,給它添加3點(diǎn)傷害,并給它火焰效果