b2c商城網(wǎng)站建設(shè)目的網(wǎng)頁(yè)關(guān)鍵詞優(yōu)化軟件
一、需求
?? ? ? ? ? ??
?二、思路一
????????HP當(dāng)然是怪物的一個(gè)屬性成員,而武器是角色的一個(gè)屬性成員,類型可以使字符串,用于描述目前角色所裝備的武器。角色類有一個(gè)攻擊方法,以被攻擊怪物為參數(shù),當(dāng)實(shí)施一次攻擊時(shí),攻擊方法被調(diào)用,而這個(gè)方法首先判斷當(dāng)前角色裝備了什么武器,然后據(jù)此對(duì)被攻擊怪物的HP進(jìn)行操作,以產(chǎn)生不同效果
package com.homework.game;public class Monster {//定義怪物名稱public String monster_name;//定義怪物血量public int monster_hp;//定義構(gòu)造方法
// public Monster(){
// }//定義有參數(shù)的構(gòu)造方法,主函數(shù)中調(diào)用此方法可以傳遞怪物的名稱和初始血量public Monster(String name,int hp){//給怪物名稱和初始血量賦值this.monster_name = name;this.monster_hp = hp;}
// //設(shè)置怪物的名稱
// public void setMonsterName(String name){
// this.monster_name = name;
// }//返回怪物名稱public String getMonsterName(){return this.monster_name;}//設(shè)置怪物的血量public void setMonsterHp(int hp){this.monster_hp = hp;}
//返回怪物血量public int getMonsterHp(){return this.monster_hp;}
}package com.homework.game;import javax.sound.midi.SoundbankResource;
import java.util.Random;public class Player {//創(chuàng)建玩家名稱變量public String player_name;//創(chuàng)建玩家武器變量public String player_weapon;//設(shè)置玩家名稱方法public void setPlayerName(String name){this.player_name = name;}//獲取玩家名稱方法public String getPlayerName(){return this.player_name;}//設(shè)置玩家武器public void setPlayWeapon(String weapon){this.player_weapon = weapon;}//獲取玩家武器public String getPlayerWeapon(){return this.player_weapon;}//玩家攻擊方法public void attackMethod(Monster monster){
// System.out.println(monster.getMonsterHp());
// System.out.println(this.player_weapon);if (monster.getMonsterHp() > 0){if("木劍".equals(this.player_weapon)){int hp = monster.getMonsterHp();hp = hp - 20;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了20HP,"+monster.getMonsterName()+"還剩余"+monster.getMonsterHp()+"血量,可繼續(xù)攻擊");}else {System.out.println(monster.getMonsterName()+"被擊殺!!!");return;}}else if("鐵劍".equals(this.player_weapon)){if (monster.getMonsterHp() > 0){int hp = monster.getMonsterHp();hp = hp - 50;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了50HP,"+monster.getMonsterName()+"還剩余"+monster.getMonsterHp()+"血量,可繼續(xù)攻擊");}else {System.out.println(monster.getMonsterName()+"被擊殺!!!");return;}}else {System.out.println(monster.getMonsterName()+"死了,不需要攻擊了!!!");return;}}else if("魔劍".equals(this.player_weapon)){if (monster.getMonsterHp() > 0){int random = ((int)(Math.random()*10))+1;int less_hp = (random > 5)?200:100;if (less_hp == 200){System.out.println("暴擊了!!!!");}int hp = monster.getMonsterHp();hp = hp - less_hp;monster.setMonsterHp(hp);if (hp > 0){System.out.println(this.player_name+"用"+this.player_weapon+"打了"+less_hp+"HP"+monster.getMonsterName()+"還剩余"+monster.getMonsterHp()+"血量,可繼續(xù)攻擊");}else {System.out.println(monster.getMonsterName()+"被擊殺!!!");return;}}}else {System.out.println("沒有武器,無法攻擊");}}else {System.out.println(monster.getMonsterName()+"死了,無需攻擊!!!");}}
}package com.homework.game;import java.util.Scanner;public class TestMain {public static void main(String[] args) {System.out.println("------------------游戲開始------------------");//創(chuàng)建怪物對(duì)象Monster monster = new Monster("魔王",500);//創(chuàng)建玩家對(duì)象Player player = new Player();//創(chuàng)建兩個(gè)錄入對(duì)象Scanner player_name_scanner = new Scanner(System.in);Scanner player_weapon_scanner = new Scanner(System.in);//定義玩家名稱變量System.out.println("請(qǐng)輸入玩家名稱:");String player_name = player_name_scanner.next();while(true){if(monster.getMonsterHp() > 0){System.out.println("請(qǐng)輸入武器準(zhǔn)備(木劍、鐵劍、魔劍):");String player_weapon = player_weapon_scanner.next();player.setPlayerName(player_name);player.setPlayWeapon(player_weapon);player.attackMethod(monster);}else {System.out.println("--------------------You Win----------------------");break;}}}
}
?小結(jié):
計(jì)的角色類的攻擊方法很長(zhǎng),并且方法中有一個(gè)冗長(zhǎng)的if…else結(jié)構(gòu),且每個(gè)分支的代碼的業(yè)務(wù)邏輯很相似,只是很少的地方不同。
再者,上述設(shè)計(jì)思路,違反了O【Open】C【Close】P原則。在這個(gè)設(shè)計(jì)中,如果以后我們?cè)黾右粋€(gè)新的武器,如倚天劍,每次攻擊損失500HP,那么,我們就要打開角色類,修改攻擊方法。而我們的代碼應(yīng)該是對(duì)修改關(guān)閉的,當(dāng)有新武器加入的時(shí)候,應(yīng)該使用擴(kuò)展完成,避免修改已有代碼。
一般來說,當(dāng)一個(gè)方法里面出現(xiàn)冗長(zhǎng)的if…else或switch…case結(jié)構(gòu),且每個(gè)分支代碼業(yè)務(wù)相似時(shí),往往預(yù)示這里應(yīng)該引入多態(tài)性來解決問題。而這里,如果把不同武器攻擊看成一個(gè)策略,那么引入策略模式(Strategy Pattern)是明智的選擇。
Tip:OCP原則,即開放關(guān)閉原則,指設(shè)計(jì)應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
Tip:策略模式,英文名Strategy Pattern,指定義算法族,分別封裝起來,讓他們之間可以相互替換,此模式使得算法的變化獨(dú)立于客戶。
三、思路二
? ? ? ? 因上述原因,我們重新設(shè)計(jì),得到以下思路
?
package com.homework.game2;
//定義一個(gè)攻擊接口,以怪物作為參數(shù),各類武器實(shí)現(xiàn)這個(gè)攻擊接口
public interface Attack {public void attcak(Monsters monsters);
}package com.homework.game2;
//武器----木劍
public class WoodenSword implements Attack {@Overridepublic void attcak(Monsters monsters) {//通知怪物失去對(duì)應(yīng)血量monsters.bloodLoss(20,"木劍");}
}package com.homework.game2;
//武器----鐵劍類
public class IronSword implements Attack{@Overridepublic void attcak(Monsters monsters) {//通知怪物掉血50monsters.bloodLoss(50,"鐵劍");}}package com.homework.game2;import javax.sound.midi.SoundbankResource;//武器-----魔劍類
public class MagicSword implements Attack{@Overridepublic void attcak(Monsters monsters) {int random = ((int)(Math.random()*10))+1;if(random > 5){System.out.println("魔劍暴擊了,擊殺200Hp!!!");monsters.bloodLoss(200,"魔劍");}else {monsters.bloodLoss(100,"魔劍");}}
}package com.homework.game2;
//怪物類
public class Monsters {//定義怪物的名稱public String monsters_name;//定義怪物的血量public int monsters_hp;
// //構(gòu)造方法,用來創(chuàng)建對(duì)象
// public Monsters(){}
// //定義怪物的構(gòu)造方法,在主方法中傳入?yún)?shù),初始化怪物屬性public Monsters(String name,int hp){this.monsters_name = name;this.monsters_hp = hp;}
// //獲取怪物名稱方法
// public String getMonstersName(){
// return this.monsters_name;
// }
// //設(shè)置怪物血量
// public void setMonstersHp(int hp){
// this.monsters_hp = hp;
// }
// //獲取怪物血量
// public int getMonsterHp(){
// return this.monsters_hp;
// }//怪物掉血的方法,參數(shù) 1.掉血量;2.使用的武器Players players =new Players("王也");public void bloodLoss(int hp,String weapon_name){if(this.monsters_hp > 0){this.monsters_hp = this.monsters_hp - hp;if(this.monsters_hp > 0){System.out.println(players.getPlayersName()+"用"+weapon_name+"攻擊了"+this.monsters_name+hp+"Hp,剩余"+this.monsters_hp+"Hp,可以繼續(xù)攻擊");}else {System.out.println(this.monsters_name+"死了,無需攻擊");}}else {System.out.println(this.monsters_name+"死了,無需攻擊");return;}}
}package com.homework.game2;
//玩家類
public class Players {//定義玩家名稱public String players_name;//定義玩家武器public Attack players_weapon;//設(shè)置玩家構(gòu)造方法,初始化玩家名稱public Players(String name){this.players_name = name;}
// //設(shè)置玩家名稱方法
// public void setPlayersName(String name){
// this.players_name = name;
// }//獲取玩家名稱方法public String getPlayersName(){return this.players_name;}//接口回調(diào) Attack weapon 接口回調(diào)變量//設(shè)置玩家武器方法,傳入接口參數(shù),將變量賦值給this.players_weaponpublic void setPlayersWeapon(Attack weapon){this.players_weapon = weapon;}
// //獲取玩家武器方法
// public Attack getPlayersWeapon(){
// return this.players_weapon;
// }//玩家攻擊方法public void player_AttcakMethod(Monsters monsters){this.players_weapon.attcak(monsters);}}package com.homework.game2;public class TestMain {public static void main(String[] args) {//創(chuàng)建怪物對(duì)象Monsters monsters = new Monsters("大魔王",200);//創(chuàng)建玩家對(duì)象Players players = new Players("王也");players.setPlayersWeapon(new WoodenSword());players.player_AttcakMethod(monsters);players.setPlayersWeapon(new IronSword());players.player_AttcakMethod(monsters);players.setPlayersWeapon(new MagicSword());players.player_AttcakMethod(monsters);}
}
改進(jìn)后的代碼有如下優(yōu)點(diǎn):
第一,雖然類的數(shù)量增加了,但是每個(gè)類中方法的代碼都非常短,沒有了以前攻擊方法那種很長(zhǎng)的方法,也沒有了冗長(zhǎng)的if…else,代碼結(jié)構(gòu)變得很清晰。
第二,類的職責(zé)更明確了。在第一個(gè)設(shè)計(jì)中,角色不但負(fù)責(zé)攻擊,還負(fù)責(zé)給怪物減少HP和判斷怪物是否已死。這明顯不應(yīng)該是角色的職責(zé),改進(jìn)后的代碼將這兩個(gè)職責(zé)移入怪物內(nèi),使得職責(zé)明確,提高了類的內(nèi)聚性。
第三,引入Strategy[策略]模式后,不但消除了重復(fù)性代碼,更重要的是,使得設(shè)計(jì)符合了OCP。如果以后要加一個(gè)新武器,只要新建一個(gè)類,實(shí)現(xiàn)武器接口,當(dāng)角色需要裝備這個(gè)新武器時(shí),客戶代碼只要實(shí)例化一個(gè)新武器類,并賦給角色的武器成員就可以了,已有的角色和怪物代碼都不用改動(dòng)。這樣就實(shí)現(xiàn)了對(duì)擴(kuò)展開發(fā),對(duì)修改關(guān)閉