作者swpoker (swpoker)
看板java
標題Re: [問題] 一個關於 strategy pattern 的疑惑
時間Fri Jun 21 11:28:16 2013
雖然說是採用策略模式
但只能說是攻擊的規劃用策略模式
那麼實作要用什麼呢?
老實說 一開始我也不知道 我都是改了三次之後 才知道要怎麼實作
在這裡我空想提供參考一下
(如果有錯字,請原諒,我會交出錯字50次的作業->複製50次就好啦 XD)
class Character{
}
interface AttackStrategy{
public void attack();
}
1.在這裡我假設用str的型態來表示策略的種類(好像不怎麼OO喔),或許用enum好點
(作法不只一種)
class AttackStrategFactory{
public static final String KnifeAttack = "0";
public static final String MagicAttack = "1";
public static final String XXXXXAttack = "2";
public AttackStrategy getAttackStrategy(String attacktype);
}
class Character {
String [] AttackStrategy ;
public void setAttackStrategy(String [] as);
public String[] getAttackStrategy();
}
class Worrior extends Character{
public Worrior(){
this.setAttackStrategy(new String[]{
AttackStrategyFactory.KnifeAttack,....
});
}
public void attack(String as){
//這裡我暫時先這樣寫,最好先建構一個facade物件,透過該facade物件來呼叫
AttackStrategyFactory.getAttackStrategy(as).attack();
}
}
如此我把角色呼叫攻擊策略分離出介面跟實作
因此腳色不需要去承擔如何產生,初始,回收該策略物件,
腳色只需要使用該策略物件就可以
我把策略物件的產生 初始 回收等等交給另外一個物件去負責
如此就比較能滿足 "單一責任原則" (雖然沒有單一責任啦)
接下來 因為我把攻擊策略的物件抽離了腳色
所以來實作一下攻擊策略工場(僅提供參考)
/*
這裡工場要採用singleton來做,所以上面要改變呼叫的方式
所以只會有一個工廠物件存在
而每個工廠物件裡面只會有各一份的攻擊策略物件
我通常會用facade+factory來提供單一入口啦(就是各物件的portal)
*/
abstract class AttackStrategFactory{
public static final String KnifeAttack = "0";
public static final String MagicAttack = "1";
public static final String XXXXXAttack = "2";
Map<String,AttackStrategy> _atks_= new HashMap<String,AttackStrategy>();
public void buildAttackStrategey(){
//這裡我亂亂寫一下,請勿當真
_atks_.put(KnifeAttack,new KnifeAttackStrategy());
....
....
}
public AttackStrategy getAttackStrategy(String attacktype){
return _atks.get(attacktype);-->假設不會亂呼叫,不然你要加入沒有的處理
}
}
又或者可以把攻擊策略工廠放在腳色裡面,但我想集中處理會比較好點
至於每個物件要使用的參數 我想那應該是另外一個議題
提供參考 謝謝大家收看
(請忽略錯字)
其實我補充一下
原PO的問題並不在"策略模式"
而是物件行為及責任
在此案例中
有兩個物件
1.腳色物件
2.攻擊物件
理論上兩個物件的關係是腳色物件使用攻擊物件
然而實際上腳色物件並不只是使用攻擊物件而已
腳色物件還得要負責生成 配置 處理該攻擊物件的生命流程
這對於腳色物件本身的責任定義來說 實在太為難腳色物件了
這也抵觸了 "單一責任原則" 每一個物件應該只負責一件事(通常不止拉)
所以原PO卡住了
不知道該如何在腳色物件裡面處理攻擊物件的生命流程
->每次切換都new一個出來嗎?然後要怎麼切換呢?
然而實際上攻擊物件的生命流程是不該由腳色物件來處理的
腳色物件僅止於知道可使用哪些攻擊物件及使用就可以了
所以我規畫另外一個物件來負責攻擊物件的生命流程
至於這個物件是要採取singleton flyweight pool都是可以討論的
但基本上是要隔離開的
不過我是有個疑問就是
就在我嘗試寫一些CODE來感受一下FULL的時候
就在我濫用樣式的時候->其實這是我常寫WEB的惡習:字串!!
(這就是TDD的好處~我幾乎可以保證我第一次的程式跟第三次的程式絕對不一樣)
這些物件的關連性有沒有很強阿?
is ,has or use
因為當我在寫attack的時候
就有再想state的問題還有腳色跟策略的關係(不過我暫且跳過就是)
腳色{
public void attack(策略物件){
策略物件.attack();
}
}
策略{
public void attack(){
我覺得很奇怪的是,怎麼會都沒有跟其他物件有關係
}
}
---
策略{
這裡其實發現 策略物件跟其他物件的關係及本身的關係
在這裡我是認為應該是->猜測!!
(我取名子很爛~雖然命名是很重要~哀)
public void attack(攻擊物件,被攻擊物件){
//或許可以提供環境 關卡的環境context,用注入的方式has
攻擊state=攻擊物件.state();
被攻擊state=被攻擊物件.state();
攻擊結果=XXXX公式(攻擊state,被攻擊state);-->template?參數直接使用物件?
or 攻擊結果=XXXX公式(攻擊物件,被攻擊物件)
攻擊物件.attackresult(攻擊結果);
-->我把處理結果交由各腳色來處理,但是否要use策略
被攻擊物件.attackresult(策略物件,攻擊結果);
}
protected void 公式(攻擊物件/狀態,被攻擊物件/狀態){
}
}
這裡就很像版主大人的攻勢
在我的想法
策略物件僅止於攻勢
各腳色提供自己(狀態?)去使用策略物件得到一些結果
然後再根據結果決定要如何反應到自身
例如獲得金牌~-->攻擊加倍/攻擊無效
但是
恩
其實跟原PO的問題無關就是XD
原PO的問題還是在於物件的生命管理及運用要怎麼規畫及實作就是
這不僅是策略物件也包含腳色物件跟其他物件都有相關
所以可以請原PO分享一下
test case给大家聞香一下嗎
包括如何建立遊戲環境
建立關卡環境
各腳色物件的生命週期管理
各物件彼此的關係
然後可以示範一場轟轟烈烈的攻擊嗎
恩~好像要求太多了 XD
因為我想要對我的專案有點靈感就是,最近有點卡住 XD
謝謝啦
PS.其實我是缺賭金的
※ 引述《ooooooo (感覺銜接最重要...)》之銘言:
: 用個之前在板上看見的例子說明,
: 假設要寫個遊戲,遊戲中有各種角色:戰士、法師、術士.....等
: 當然每個角色都有技能可以攻擊。
: 我構想的設計是,
: class Character{ //各種角色的 super class
: attackStrategy atk ; //用來攻擊的策略
: public void attack(){
: atk.attack();
: }
: }
: class Warrior extends Character{
: //warrior 使用 knife 進行攻擊
: AttackStrategy atk = new KnifeStrategy();
: }
: class Wizard extends Character{
: //wizard 可使用fireball攻擊
: AttackStrategy atk = new FireBallStrategy();
: }
: 其他角色以此類推。
: 關於 AttackStrategy、KnifeStrategy、FireBallStrategy
: 就是strategy 模式,code 我就不寫了。
: 我的問題在於,假設一個角色,不只有一種技能可以攻擊,
: 也就是依照角色的不同,可能有不同的攻擊技能的時候。
: ex wizard 可以用 fireball、也可以用 fireStorm
: 但 warrior 只能用 knife
: 那當一個 wizard 在切換 fireball 與 fireStrom 攻擊的時候,
: 該怎麼去處理?
: 若每次切換,就 new 出來一個對應的 strategy ,感覺好像怪怪的,
: 萬一切換次數一多,不就一堆垃圾物件?(當然 java 會自己回收。)
: 但我還是覺得怪怪的,感覺應該有更好的方法可以處理這樣的行為才對,
: 麻煩板友指點一下,有種卡住的感覺,謝謝。
: ps.1.code 的意義應該夠清楚,如果有任何需要說明的,推文一下,我會補上
: 2. 很久沒寫 java 了,這邊的 code 都直接手打沒編譯過,
: 如果有 typo 請大家見諒,請當成 pseudo code 來看。
--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 163.29.29.131
→ tkcn:腳色 -> 角色 06/21 11:29
推 cowbaying:用繼承會不會好一點? 06/21 12:24
→ swpoker:繼承在實作的時候會出現盲點及混亂-->繼承VS原型之爭阿 06/21 12:36
※ 編輯: swpoker 來自: 163.29.28.131 (06/21 14:43)
推 ooooooo:感覺這文章開頭相當有 TDD 的風格! 06/21 16:47
→ swpoker:沒錯!!TDD最高!!! 06/21 16:52
→ swpoker:腳色跟攻擊很有IOC的味道喔 06/21 16:54
推 ooooooo:感謝,這兩天看幾位板友的回文與推文,有突破盲點了~ 06/23 00:09
推 PsMonkey:說好的(?)突破盲點文咧? 06/23 18:12
推 ooooooo:我覺得主要盲點就是在strategy obj 的生成,應該交由更合 06/23 23:36
→ ooooooo:適的obj來負責。至於詳細怎麼做,週日沒進公司,週一研究 06/23 23:38
※ 編輯: swpoker 來自: 163.29.28.131 (06/24 10:15)
→ swpoker:我最後的例子出現雙向相依的問題(注意!) 06/24 17:02