设计模式——策略模式(java)

时间:2022-10-01 21:22:57

  在开始看设计模式之前我们先复习一下oo的设计基础和设计原理

   设计模式——策略模式(java)

                                   图1

   原文章链接:点击打开链接

     设计原理(并不是全部,只是这个模式所用到的):

         设计模式——策略模式(java)

                                 图二

         设计模式——策略模式(java)

                                 图三

         设计模式——策略模式(java)

                                 图四


  策略模式的定义:定义了算法族,分别封装起来,让他们之间可以相互替换,这个模式让算法的定义独立于使用算法的客人

  看了这个定义你也许对策略模式是一头雾水,别急,接下来我们用一个实际项目来理解


项目名称:模拟鸭子

项目描述:这是一个模拟鸭子的游戏,游戏中会出现各种各样的鸭子,有绿色羽毛游水的真鸭,有会游水的黄色橡皮鸭,还有会飞正在呱呱叫的鸭子...... 

项目分析:首先这个项目的对象很清晰,就是鸭子,但是我们需要给鸭子赋予不同的属性,在这些属性中有些是不变的(每个鸭子对象都会有的),比如:鸭子的外观,还有一些是变化的(不是所有的鸭子都会的),比如:鸭子的飞行,叫声

项目设计

  注:extends设计模式——策略模式(java)

    implement设计模式——策略模式(java)

一.(未使用策略模式,单纯使用继承):

         设计模式——策略模式(java) 

                                          图六

  出现的问题:1.代码在多个子类中重复(不同的鸭子子类需要去覆盖父类中方法)

          2.运行时的行为不容易改变(如要修改其中一个鸭子的行为就必须要修改覆盖父类方法的代码)

          3.很难知道其中某个鸭子的所有行为

          4.改变会牵一发而动全身,造成其他鸭子不想要的改变

二.(使用了策略模式):

设计模式——策略模式(java)

                                               图七

 上面设计中出现的问题,我们根据文章开头提到的设计原理做一步步的改造

  首先根据原则一,我们要把鸭子中会变化的属性单独提出来,也就是上述分析中的飞行动作和叫的动作,建Flyable和Quackavle接口有需要这些属性的鸭子就implement接口

设计模式——策略模式(java)
                                           图八  出现的问题:因为接口不具备具体的实现,以至于我们在鸭子实例中还是要具体的实现,还是存在上面的问题

  根据原则二:在上面一个解决方法中,虽然每个具体的鸭子类implement了接口,但是在这些鸭子类中还是要去具体去实现接口,这就是针对实现编程,而我们的目的在于针对接口编程。
  原则二解释:声明一个接口类型的变量,但是new(实现)的时候却是一个实现类(此类implement了这个接口,运用了多态)

设计模式——策略模式(java)
设计模式——策略模式(java)
 在这个模型中我们创建了不同的实现类(FlyWithWings,FlyNoWay)去implement Fly这个接口,在这些类中具体的写出飞的方法,需要飞行动作的类就可以声明Fly接口的变量,然后这个变量再new具体的实现类。(叫的动作实现的方法也是一样的)

设计模式——策略模式(java)

                                               图九

  据原则三,使用组合把这个项目整合,在Duck类中声明飞的变量flyBehavior(implement Fly),在飞的方法中去调用接口中的方法flyBehavior.fly()(fly()在Fly接口中定义了),这样一来Duck类中就可以完全不需要知道具体的飞的方法,它只需调用接口的方法就可以。(叫也是同样的做法)

设计模式——策略模式(java)

                  图十

然后不同的鸭子类去extends这个Duck类,引用Duck类中的flyBehavior变量去new一个FlyWithWings类,这样一来这个鸭子就有了翅膀飞行的属性了。这些具体的鸭子是通过组合形成的,虽然用到了继承但是总体来说鸭子的其中飞行动作是一个类,这个类和其他的属性组合成了一个具体的鸭子。


  好了,到这里这个项目的整个设计已大概完成。我们这篇文章的重点策略模式不知你是否在心中已有了一个概念,最后我们再重新梳理一下这个策略。

  首先这个策略的重点在于定义算法族并进行封装,回顾上述的项目,我们把鸭子的行为说成是“一组行为”也就是策略上的“一族算法”,鸭子的不同属性(不同的叫和飞)代表了算法,然后我们封装了这些算法。且这些封装的算法独立于客户,客户还可以动态的互相替换(图七)

  本文到这里已全部结束,恭喜你!又学到了一点新的内容!

  


             注:本文中所有图片全都来自《Head First设计模式》一书中的截图

  参考:《Head First设计模式》