论坛首页 Java企业应用论坛

设计模式解读之一: 策略模式

浏览 35458 次
精华帖 (11) :: 良好帖 (4) :: 新手帖 (16) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-08-03  
xu_zh_h 写道
hunter001201 写道
这种解释就是误导。

本身鸭子这个例子就没有可以用策略模式的影子。


的确看不见策略的影子


有啊,鸭子的例子是作者从Head First上搬过来的,上面对策率模式比喻的非常形象,从抽象类讲到接口,再从接口讲到策略模式,非常的有道理。

下面是我根据鸭子的例子得出的结论,为什么要使用策略模式:

    * 世界上的对象,都可被归结为一个类别,于是有了类

    * 但类中的对象都有细微的差别,包括特性(属性)和行为(方法),于是有了接口和抽象类,并产生OO的三大特性:封装,继承,多态(有书上说四大特性,还包括抽象)

    * 类是对特性和行为的封装,接口和抽象类是体现差异化,通过继承来实现多态

    * JAVA中的类继承抽象类的缺陷在于,两个不同的子类可能有不同的行为,而都继承一个抽象类,则表现为,一个子类分明没有某一行为,但因为继承了抽象类,它必须实现这一抽象行为,却什么也不做,这不是一个好的策略。

    * 于是有了接口,同一类的不同子类因为有不同的行为,可以将所有子类共同的行为抽象出来,放在抽象父类中来继承,不同的行为在放在不同的接口中来实现,这样看来,貌似是一个很好的设计策略,其实仍有一个很大的缺陷,如果有20个子类同时具有某一接口的特性,那么这一特性要被实现20次,这将出现大量的重复设计。

    * 于是,策略模式闪亮登场。将这些被大量重复的行为剥离出来,另建一个对应于原类的“行为类”,并让原类拥有一个行为类的依赖,当调用原类的某一行为时,事实上是委托其依赖的行为类上的对应的方法。

    * 策略模式的好处在于,将子类中共同的行为剥离出来,放在行为类中,让子类动态的绑定行为类,多个子类具有相同的行为,就可以绑定用一个行为类,而不必全部实现某一接口。更重要的意义在于,这是一种松耦合的设计原则,采用了组合代替继承的方式。每个子类都可以动态的定制行为类
0 请登录后投票
   发表时间:2009-08-03  
xiaoqulai 写道
xu_zh_h 写道
hunter001201 写道
这种解释就是误导。

本身鸭子这个例子就没有可以用策略模式的影子。


的确看不见策略的影子


有啊,鸭子的例子是作者从Head First上搬过来的,上面对策率模式比喻的非常形象,从抽象类讲到接口,再从接口讲到策略模式,非常的有道理。




这个例子作为讲解针对接口编程是合适的,但作为策略模式例子不合适。至于这个编程原则在很多模式都有应用
0 请登录后投票
   发表时间:2009-08-05  
wujie2008 写道
总结的不错。受益匪浅。学习中。
我认为楼主的意思是:
   1.通过继承实现的代码复用容易引起牵一发而动全身的弊端。而且在父类中添加方法可以使不用拥有此方法的类也拥有此方法。
   2.通过组合实现的代码复用更具弹性,而且便于扩展。
   3.面向抽象编程可以提高程序的复用率。增加灵活性。
   4.策略模式的核心是,将问题的可变性和不可变性分开处理,将可变性单独抽取成接口,并且按照具体策略对其进行不同的实现,再通过类的组合达到代码复用,避免继承复用代码,每当需要添加新的方法是,就添加对应的接口和实现类,解决继承造成的代码复用问题。

不知理解的对不对,
另外有一个问题:
  当需求不断变化,需要添加许多的方法,而且有不同的实现,那么系统的类是不是会呈现爆炸式增长。怎么解决这个问题。

当需求不断变化,需要添加许多的方法,而且有不同的实现,那么系统的类是不是会呈现爆炸式增长。这个问题有什么办法解决吗?还是说,策略模式的局限性就在这里?
0 请登录后投票
   发表时间:2009-08-07  
thanks。楼主分析得不错。
0 请登录后投票
   发表时间:2009-08-12  
最终目的都是解耦
0 请登录后投票
   发表时间:2009-08-12  
我想问下,假设我要实现的是橡皮鸭(它不会飞,但却定义了飞的动作),那在这个例子中使用策略模式怎么实现?
public abstract class Duck {
            //将行为类声明为接口类型,降低对行为实现类型的依赖
        FlyBehavior flyBehavior;
        QuackBehavior quackBehavior;

        public void performFly() {
            //不自行处理fly()行为,而是委拖给引用flyBehavior所指向的行为对象
            flyBehavior.fly();
        }

        public void performQuack() {
            quackBehavior.quack();
        }

        public void swim() {
            System.out.println("All ducks float, even decoys.");       
        }
       
        public abstract void display();
       }

0 请登录后投票
   发表时间:2009-09-18  
策略模式的本质是:少用继承,多用组合。
0 请登录后投票
   发表时间:2009-09-18  
wujie2008 写道
总结的不错。受益匪浅。学习中。
我认为楼主的意思是:
   1.通过继承实现的代码复用容易引起牵一发而动全身的弊端。而且在父类中添加方法可以使不用拥有此方法的类也拥有此方法。
   2.通过组合实现的代码复用更具弹性,而且便于扩展。
   3.面向抽象编程可以提高程序的复用率。增加灵活性。
   4.策略模式的核心是,将问题的可变性和不可变性分开处理,将可变性单独抽取成接口,并且按照具体策略对其进行不同的实现,再通过类的组合达到代码复用,避免继承复用代码,每当需要添加新的方法是,就添加对应的接口和实现类,解决继承造成的代码复用问题。

不知理解的对不对,
另外有一个问题:
  当需求不断变化,需要添加许多的方法,而且有不同的实现,那么系统的类是不是会呈现爆炸式增长。怎么解决这个问题。


分析得很透彻,肯定会出现爆炸式增长的局面,但是这种情况怎么解决?
0 请登录后投票
   发表时间:2009-09-19  
总感觉在使用瀑布模型开发项目时候,客户的需求不断改变,导致项目开发效率低下,看到了圆形模式和循环开发模式,今天又看到了这个策略模式。
0 请登录后投票
   发表时间:2009-10-12  
终于比较清楚的理解了策略模式,有一点不是很明白 。如果使用继承的方法,不是可以通过方法复写来改变父类的行为。因为我看到在使用策略模式的时候,看到橡皮鸭同样包含了fly方法,照理说它 不应该有这样的行为。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics