《Head.First设计模式》的学习笔记(2)--策略模式

先对策略模式有一个总体认识。

意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

结构

image

下面通过鸭子模拟器的设计来具体介绍。

公司需要设计一套鸭子模拟器系统,该系统的第一次需求为:鸭子能够戏水;鸭子能够呱呱叫。根据该需求系统设计如下:

image

这个设计主要用了父类鸭子和子类绿头鸭、红头鸭,这样设计的目的是为了达到代码的复用。

过了一段时间,公司希望该系统能够满足新的需求:有些鸭子会飞。因此该系统需要进行修改,修改后的系统可能如下:

image

该系统在父类中加了“fly()”方法(在父类中加该方法是为了实现代码的复用)。这里就出现了两个问题:

(1)、所有的鸭子都会飞了。

(2)、所有鸭子的叫声都一样,都是“呱呱”叫。

注:这两个问题可以通过子类中方法覆盖来解除,但这样处理不是很好。鸭子的类别越多,这种处理的缺点就越明显。

其实这个系统的变化点是鸭子的叫声和鸭子的飞行能力,因此我们很容易想到把鸭子的叫声和鸭子的飞行能力做成接口,把这些变化的地方封装起来,这样上面的两个问题都可以解决,所以系统可能被修改为下面的样子:

image

MallardDuck和RedheadDuck既会飞又会叫,RubberDuck只会叫不会飞,DecoyDuck不会飞也不会叫。应该说这个系统没有问题了,从表面看这种设计完全符合需求,而且完全符合面向对象的理念,但是当鸭子的类别很多时,你会发现这种设计缺乏代码的复用,这两个独立出来的接口似乎没有任何意义,根本无法减轻工作量,还不如原来的设计呢。所以你可能会想到问题的关键是接口中的方法没有实现,那我们该怎么办呢?

我们的做法是把接口做成类,运用组合的方法来实现需求。考虑到“针对接口编程,而不是针对实现编程”的设计原则,我们的系统可能就会设计成如下的结构,这个结构就是应用了“策略”模式。
image
 
源代码下载/Files/wxj1020/MiniSimuDuck.rar

Tag标签: 设计模式
posted @ 2008-03-21 00:12 鹰击长空 阅读(2887) 评论(19)  编辑 收藏 所属分类: 设计模式

  回复  引用    
#1楼 2008-03-21 08:32 | 盒饭 [未注册用户]
来支持一下,写得不错。
  回复  引用  查看    
#2楼 2008-03-21 09:29 | candylight      
支持一下,挺喜欢看《Head First》系列的,特别是那句橡皮鸭在天上飞~~
  回复  引用    
#3楼 2008-03-21 10:04 | marklch [未注册用户]
我想问的是这个哪里有中文版的下载?
  回复  引用    
#4楼 2008-03-21 10:11 | 朝霞沐浴青松 [未注册用户]
支持!不错
  回复  引用  查看    
#5楼 2008-03-21 10:21 | Tony Zhou      
这书我也在看,我先前看了其他得书。
看他推导的过程,我就想他最后一定说这是个bridge,没想到他说是strategy,为什么呢?按head first的说法,如果这个例子要能用上bridge,又要有哪些附加条件呢。
不知道楼主有啥见解。
也希望高手解惑。

  回复  引用  查看    
#6楼 2008-03-21 10:37 | floodpeak      
这确实是本好书
  回复  引用  查看    
#7楼 2008-03-21 10:55 | Ryan Yu      
这本书讲模式讲得挺好
  回复  引用  查看    
#8楼 2008-03-21 10:58 | Tristan(Guozhijian)      
@Tony Zhou

Strategy:一个context对应一组算法族,context与算法是1 ... *关系
Bridge:context本身也是一个继承体系,也就是一组具体context对应一组行为实现,相当于 *...*关系

当bridge的context体系退化为只有一个context对象(bridge左边的*退化为1)的时候,它就是一个strategy了。

:)
  回复  引用  查看    
#9楼 2008-03-21 11:17 | Tony Zhou      
@Tristan(Guozhijian)
受教!
但是还是有个疑问,如果看一下它duck的结构图,就会发现,他的duck也是一组。有很多不同的duck。这个是不是“一组具体context”呢?或者说我的理解有误,一组context并不是几个继承这样简单?

我觉得可能这本书的作者和别人理解稍有不同。两个模式设计的思路其实大同小异。我这样专门的要去讲他的区别,可能也有点较真。


  回复  引用  查看    
#10楼 2008-03-21 11:21 | Tristan(Guozhijian)      
@Tony Zhou
不敢。

Head first Design Pattern我看了,现在印象已经不是很深刻。
我认为Strategy和Bridge本是一家。
都是将容易变化的行为抽象出来。
具体的,怎么好用就行了吧:)

  回复  引用  查看    
#11楼 [楼主]2008-03-21 12:41 | 长空新雁      
@marklch
这本书的电子版在下面这个网站上可能有,我是以前下的
www.shubulo.com
  回复  引用  查看    
#12楼 [楼主]2008-03-21 12:47 | 长空新雁      
@Tony Zhou
我认为Strategy对应一组算法,即算法是可以变化的,可以动态的改变,而
Bridge是静态的,说白了就是一个算法。我刚开始学这些东西,希望高手指点。
  回复  引用  查看    
#13楼 2008-03-21 13:42 | Tony Zhou      
@长空新雁
bridge我理解应该不是一种算法,应该是和Tristan(Guozhijian)说的差不多。
  回复  引用  查看    
#14楼 [楼主]2008-03-21 14:06 | 长空新雁      
@Tony Zhou
我认为Strategy是动态的,Bridge是静态的,可能表达不是很清楚,引起误解了。希望多多交流,共同提高。
  回复  引用  查看    
#15楼 2008-03-21 14:59 | Marklee      
@长空新雁
非常感谢,主页就有下的,之前我下了一个版本,是个阉割版,看了第一章就没了,郁闷的吐血
  回复  引用  查看    
#16楼 2008-04-11 14:40 | Leon916      
我个人觉得用鸭子模拟器来解释策略模式不是很好,因为按照博主的图,每一个鸭子都有两个接口,其中一个是Fly,但是就鸭子而言,有些鸭子根本就没有不需要这个接口或者说没有这个能力,为什么还需要硬生的给每一个鸭子加上这个接口呢?
  回复  引用  查看    
#17楼 [楼主]2008-04-14 09:27 | 长空新雁      
@Leon916
你说的没错,具体项目是很少会这么用的,但用在这里只是为了阐释这个模式。 不会飞的鸭子引用的代码是这个
public string Fly()
{ return ("I can't fly!!!"); }
应该说也没有什么问题。

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-21 00:23 编辑过
 
另存  打印