关于Head First设计模式中的策略模式的困惑

09-03-23 freesea
大家好,最近在jdon学习了一段时间,买了本关于模式的书来学习,<Head first 设计模式>中的第一个模式策略模式(Strategy),其中有三个设计原则:

1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起

2、针对接口编程,而不是针对实现编程

3、多用组合,少用继承。

策略模式定义了算法族,分别封装起来,让它们之间可以互想替换,此模式让算法的变化独立于使用算法的客户。

它举了一个SimuDuck的列子,使用的是策略模式,如下图

http://www.jdon.com/jivejdon/imageShow.jsp?id=0

其实我有点困惑,根据原则1 2 3为什么不把行为再拿出来,抽像一个更高级别的接口呢,而是把飞行行为和呱呱叫行为单独出来呢?假如鸭子要求还有其它行为,那不是又要修改Duck类吗?我觉得因该抽像出一个Behavoir接口(只是一个像征意义的类型,没有实体),飞行行为和呱呱叫行为因该实现行为接口,这样有新的行为时,就不需修改Duck。请banq指点一下,这样可以吗

[该贴被freesea于2009-03-23 20:38修改过]

Head first

BluE11
2009-03-23 21:45
我觉得 每个模式都有其 适应的 场合

像 策略模式 就 适应于 解耦 对象中的行为算法(可以是一个行为算法中的一小块,当然也可以是全部), 而不是 封装 对象的所有行为, 所以, duck类 要添加 行为的 话, 与 策略模式 就没有 本质上的 联系, 因为, 如果, 你添加的 行为 是 FlyWithQuack, 我 想你是 不 需要 添加 一个 新接口的。(当然, 修改类 是 必需的)

再有 就是, behavior的 整体封装,

我觉得, 还是 要 看场合, 要是 , 对象的 行为算法 之间 有 很 必然的 联系, 无法 分割, 那 整体封装,是 最好的

但 像 例子中 那样,分割开后是 最好的,因为 , 倘若封装在一起, 两个算法其中 只要有一个 发生 变化的话,

你就 需要 重新 写 一个 实现类, 也就是 说 你 违反的 原则1

freesea
2009-03-23 23:05
BluE11

我其实没看明白你所说的意思,我可能表过不太清楚,用代码来表达吧

Behvior.java

interface Behavior{

}

----------------------------------

FlyBehavior.java

----------------------------------

interface FlyBehavior extends Behavior{

}

----------------------------------

QuackBehavior.java

----------------------------------

interface QuackBehavior extends Behavior{

}

----------------------------------

Duck.java

----------------------------------

public abstract class Duck{

Behavior bh;//关键在这里,不管有什么样的行为,

//这个duck类都不用修改了

}

而不是像原来那样

public abstract class Duck{

FlyBehavior fb;//飞的行为

QuackBehavior qb;//叫的行为

......//如果再加其它行为,那么这里不是要修改么

}

OOLA
2009-03-24 10:21
如果像您这样的提取一个新的接口,而又希望用户只和此接口交互以防止Duck类的变化,那么这个新的接口也就会有被污染的可能,如果其子接口的只有一个行为语义的话,新接口还可以应对(如public vodi action()),多个的话就不能应对了,新接口承担了不相关的行为集,职责不单一;如果只有一个行为语义的话,新接口也就没有必要了。

BluE11
2009-03-24 12:26
我想 我 是 没 理解 你的 意思, 因为 我 发现 你的所表达的意思 是 矛盾的

interface FlyBehavior extends Behavior{
}
interface QuackBehavior extends Behavior{
}
<p>

这是 两种 行为 的 接口

public abstract class Duck{
Behavior bh;//关键在这里,不管有什么样的行为,
//这个duck类都不用修改了
}
<p>

这里 只有 一个 行为 接口,

如果 你 只想要 Duck 有 一种 行为, 那么 我 同意 你的 说法, 但 这 就和 策略模式 不相关了

但 如果 Duck 要 添加 一种 行为(同时 有 2 种待行为), 你 说说看 怎么 不 修改 Duck,

除了 装饰模式外, 你 可能 只 能 将 两种行为 都 放到 Behavior 的 一个 实现里, 这样 是 不科学 的 。。。。

不知道 , 这次 我 理解 对了 没有

猜你喜欢
2Go 1 2 下一页