作者adrianshum (Alien)
看板java
标题Re: [问题] 一个关於 strategy pattern 的疑惑
时间Sun Jun 23 23:04:26 2013
开宗明义第一句:Stragety 做成 Singleton 不是正解,
不要浪费时间。(後面再来详解)
首先,Strategy 解决的问题是,把不同情况需要不同的
逻辑,包装成所谓 Strategy, 然後只要替换 strategy,
就能不影响caller 的 code 之下做到不同的工作。(
很大概的说法)。
回到你的问题,在替换 strategy 究竟需不需要每次生成,
这根本不是 Strategy 涵盖的范围。
解决方法可以很多。每次生成当然可以(後面再说怎麽
解决你的担心),更直接的是,一个 Character 可以存
着自己可用的技能, 所谓替换,就是在手头可用的技能
拿出对应的来使用而已:
class Character {
AttackStrategy activeAttackStrategy;
List<AttackStrategy> attackStrategies;
void selectStrategy(int index) {
activeAttackStrategy = attackStrategies.get(index);
}
}
或者用类似的想法。简单而言,要替换,并不代表每次要生成
新的。
然後有些回应提到用 把 strategies 做成singleton。请千万不要。
在这种情况下99% 不是正解。Singleton 的用意是这 class 在意义上
在整个系统只存在一份,但这些 Strategy 并没有这样的需要。更何况,
很多时候一个 strategy 会存有 state, 例如:
class FireballStrategy implements AttackStrategy {
int level = 1;
public void setLevel(int level) {...}
public void attack() {
reduceHpBy(level * 100);
}
}
这样怎麽可能适合用 singleton 呢?就算你的设计上不存在 state,
概念上你的 strategy 也不是 singleton。
要是你担心生成太多,解决方法也应该是 Flyweight pattern 而非
Singleton。
至於有一篇回文大概是存个 string 然後每次找 factory 去拿
strategy 再 invoke,个人觉得只是换汤不换药,再加上上面提
到 strategy 很多时候是有internal state 的,这种解决方法
并不理想。把 factory 弄成 singleton 更是不必要。这可以算是
滥用 singleton 的好例子 :p
(整个讨论本身好像和 Java 没太大关系...)
Alien
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 223.19.42.175
※ 编辑: adrianshum 来自: 223.19.42.175 (06/23 23:11)
※ 编辑: adrianshum 来自: 223.19.42.175 (06/23 23:15)
※ 编辑: adrianshum 来自: 223.19.42.175 (06/23 23:19)
1F:推 ooooooo:感谢,这篇揭开了一开始我听到 singleton 莫名不安的原因! 06/23 23:42
2F:→ TonyQ:同意 06/24 06:24
3F:推 PsMonkey:呜呜... 单纯作成公式不好吗? [泪目] 06/24 08:10
4F:→ PsMonkey:还想确认一下,这里套用 flyweight pattern 不会出问题吗 06/24 08:22
5F:→ PsMonkey:我狗了一下几个范例,flyweight 的 class 都没有 setter 06/24 08:24
6F:→ swpoker:厘清物件的责任~样式混用~我的例子是工厂环境单一~ 06/24 08:49
7F:→ swpoker:虽是单一~程式其实没有单一~而是用注入来做 06/24 08:53
8F:→ swpoker:哈~我後来有补充~就是解释你的问题 06/24 08:56
9F:→ adrianshum:PsMonkey: strategy 就是代表公式,只是想把公式替换 06/24 09:07
10F:→ adrianshum:另 Flyweight 重点是存着一份重覆使用,当然没 setter 06/24 09:08
11F:→ adrianshum:的 immutable obj 比较合,所以我也提及 strategy 会有 06/24 09:10
12F:→ adrianshum:internal state, 套singleton (flyweight) 或会出问题 06/24 09:11
13F:→ adrianshum:@swpoker:另有factory去生成strategy没错(有没有必要 06/24 09:13
14F:→ adrianshum:另一问题),可是错在每次去找factory生成。这样的 06/24 09:14
15F:→ adrianshum:strategy 用法并不恰当。另当中提到 facade也是多余的 06/24 09:15
16F:→ adrianshum:建议你先把pattern 作最少的使用并用得清楚,再来套更 06/24 09:16
17F:→ adrianshum:多 pattern. 我在你的回应中嗅到滥用pattern的味道 06/24 09:16
18F:推 PsMonkey:喔喔... 我把整篇文章混在一起看了,所以误会了 XD 06/24 09:21
19F:→ swpoker:其实这是我刚开始想的~首先HELLO WORLD然後再重构 06/24 09:36
20F:→ swpoker:利用TDD来作为开始,并且用来确认整理厘清物件及行为 06/24 09:38
21F:→ swpoker:好吧我只点出问题并不在"策略样式"而已~ 06/24 09:41