sb do sth和sb doing:斐波那契数列算法分析

来源:百度文库 编辑:中财网 时间:2024/05/04 07:34:15

Head First 设计模式

第一章 欢迎来到设计模式世界 —— 策略模式

一,鸭子问题:

Joe上班公司做了一套相当成功的模拟鸭子游戏:SimUDuck。游戏中有各种鸭子,边游泳戏水,边呱呱叫(注意是“呱呱叫”)。显然Joe使用了OO技术,设计了鸭子的基类。由于每个鸭子的长相不同所以Display()方法是抽象的,Duck类也是抽象类。

但是,最近公司为了开了头脑风暴会议,要更新产品,并决定通过让鸭子会飞来击败竞争者。这时Joe应该怎么办呢?

二,Joe的方案

方案一:

毕竟Joe是个OO程序员,这个对他来说一周不到就可以搞定了。他的做法是在Duck类中加上fly()方法,这样不是所有的鸭子都会继承fly()了嘛~~^_^(注意:Joe认为所有的鸭子都会飞,而且飞起来都是一样的,所以就只要在基类中实现fly()方法就行了……)

但是可怕的发生了……

在股东会议的展示上,很多的“橡皮鸭子”飞了起来,看来Joe要去求职网站(Monster.com)去逛逛了……原来Joe忽略了:并非所有的鸭子都会飞。在基类中加上的方法将使得那些不适合该行为的派生类也具有了这种行为。

所以,对代码做的局部修改,影响的层面不只是局部!!

看来,涉及到“维护”时,为了“复用”而使用继承并不完美。

方案二:

Joe心里想,不就是橡皮鸭子不会飞嘛,那我在橡皮鸭子类(RubberDuck)里重写一个fly()方法,这个方法什么也不做不就行了,而且橡皮鸭子不会呱呱叫,但是会吱吱叫,那就在RubberDuck类里覆盖quack()方法,写成吱吱叫不就行了~~^_^。(但是,如果以后再引入了诱饵鸭怎么办,只能再覆盖fly()quack()方法呗~~)。

看来Joe认识到了继承可能不是解决这个问题的答案了,因为他刚刚接到通知,希望以后每六个月就更新产品一次,这样每当有新的鸭子类出现他就要去覆盖,真是一个噩梦!!

利用接口如何??

Joe说:“我可以把fly()方法从超类中取出来,放进一个”Flyable“的接口中。这么一来只有会飞的鸭子才实现这个接口,当然也可可以用来设计一个”Quackable”的接口啊~”。

这个设计怎么样??

这个时候,小秘又偷偷打电话给Joe说:“这真是一个超笨的主意!!这么一来重复的代码更多了,如果你认为覆盖几个方法是差劲,那么对于一个有48Duck子类都要稍微修改一下飞行的行为,你该怎么说?!!“。

这时候,Joe应该怎么办呢??

我们知道,并不是所有的派生类都具有飞行和呱呱叫的行为,所以继承不是适当的解决方案。虽然上面的接口FlyableQuackable可以解决“一部分“问题,但是造成了代码不能复用,这只能算是从一个噩梦跳到另一个噩梦。甚至在会飞的鸭子中,飞行的动作的不一样~~

我们的第一个设计原则的想法是,把会变化的部分取出并且“封装”起来,好让其他部分不会收到影响。这样使得代码变化不经意的后果变少系统更有弹性。

换句话说,每次来新的需求,就会使某方面的代码发生变化,那么我们就可以确定,这部分的代码需要被抽出来,跟其他的代码有所区分。

这种原则的另一种思考方式:“把会变化的部分取出来并且封装起来,以便以后可以轻易的改动或者扩充这一部分,而不影响不需要变化的其他部分”。

使系统重的某部分改变不会影响其他部分!!

 

方案三:

1,分开变化和不变化的部分

目前,除了fly()quack()的问题之外,Duck类还算一切正常。为了分开“变化和不变化的部分”,准备建立两组类(完全远离Duck类),一个是fly相关的,一个是quack相关的。每组实现各自的动作。也就要把flyquack行为从Duck类中分离出来,建立一组新的类。

2,设计鸭子的行为

下面就要讨论如何去实现飞行和呱呱叫的行为的类。

我们希望一切能有弹性。例如,我们想要产生一个新的绿头鸭实例,并且指定特定“类型”的飞行行为给它。我们目的是让鸭子的行为可以动态改变(运行时可以改变,例如橡胶鸭子不能飞,给它加个助燃器就能像火箭一样)。

我们第二个设计原则的思想是,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。这样鸭子就不需要知道行为的实现细节了。

 

现在我们就用接口代表每一个行为,如下:

这下子鸭子不需要实现FlyBehavior与QuackBehavior接口,由我们专门的一组类实现之。这就是我们的“行为类”

以前我们的做法是:行为都是来自Duck超类具体实现,或者是继承某个接口并且由子类自行实现而来的。这都是依赖于“实现”的,我们就被实现绑得死死的,很难修改行为。

新的设计中,鸭子的子类将使用接口来表示行为,所以实际的“实现”不会绑死在鸭子的子类中(实现放在了行为类中了)。

“针对接口编程”真正意思是“针对超类型编程”!

上面的口号就是告诉我们,充分利用多态,我们变量的声明类型应该是超类型,一个抽象类或者一个接口,这样一来只要是实现了此超类型的类所产生的对象,都可以指定这个这个变量。

3,实现鸭子的行为

在此我们给出两个接口和对应的实现他们的类。

4,实现鸭子的行为

1,我们现在Duck中加入两个实例变量

2,我们现在的Duck类:

5,动态设定行为

在鸭子里建立了一堆的动态功能前面都没怎么用到,这很可惜。我们想在鸭子子类中通过“设定方法”来设定鸭子的行为,而不是在鸭子的构造器内实例化。

三,总结

策略模式:就是定义一系列的算法方法,并它们都封装起来,使它们都独立起来,并且使它们可以相互替换。该模式使得算法可独立于它们的客户变化。主要是应对:在软件构建过程中,某些对象使用的算法可能多种多样,经常发生变化。如果在对象内部实现这些算法,将会使对象变得异常复杂,甚至会造成性能上的负担。