作者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
1F:→ tkcn:脚色 -> 角色 06/21 11:29
2F:推 cowbaying:用继承会不会好一点? 06/21 12:24
3F:→ swpoker:继承在实作的时候会出现盲点及混乱-->继承VS原型之争阿 06/21 12:36
※ 编辑: swpoker 来自: 163.29.28.131 (06/21 14:43)
4F:推 ooooooo:感觉这文章开头相当有 TDD 的风格! 06/21 16:47
5F:→ swpoker:没错!!TDD最高!!! 06/21 16:52
6F:→ swpoker:脚色跟攻击很有IOC的味道喔 06/21 16:54
7F:推 ooooooo:感谢,这两天看几位板友的回文与推文,有突破盲点了~ 06/23 00:09
8F:推 PsMonkey:说好的(?)突破盲点文咧? 06/23 18:12
9F:推 ooooooo:我觉得主要盲点就是在strategy obj 的生成,应该交由更合 06/23 23:36
10F:→ ooooooo:适的obj来负责。至於详细怎麽做,周日没进公司,周一研究 06/23 23:38
※ 编辑: swpoker 来自: 163.29.28.131 (06/24 10:15)
11F:→ swpoker:我最後的例子出现双向相依的问题(注意!) 06/24 17:02