zoukankan      html  css  js  c++  java
  • 策略模式

    定义

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

    类图


    设计原则

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

          2.针对接口编程。而不是针对实现编程。

          3.多用组合。少用继承。

       

    举例分析

        设计一个模拟鸭子游戏,游戏中会出现各种(木头鸭、橡皮鸭等等)鸭子。一边游泳(swim)。一边叫(quack)。系统类图例如以下:


    去年。公司的竞争压力加剧,此类游戏非常多。公司开会决定要对游戏进行升级,要求有些鸭子会飞。程序要Joe是这样设计的,例如以下:


           程序完毕后,当在股东会议上演示的时候,有非常多“橡皮鸭”竟然会飞。(方法覆盖能够解决此问题,假设有100个不同类型的鸭子。就得重写100次。

    在超类Duck中加上fly()方法。就会导致全部的子类都具备fly()。连那些不该具备fly()的子类也无法免除。

    Joe认识到继承可能不是答案,于是Joe有设计了一种方法。例如以下:



            Joe的上司看了这个设计后,这真是一个超笨的注意,你没有发现这么一来反复的代码会变非常多吗?(全部须要quack()fly()方法的鸭子都去反复实现这两个方法)假设你觉得覆盖几个方法就算是差劲。那么对于100个Duck的子类都要改动一下飞行(fly())的行为。你又怎么说。

           我们知道。并非全部的鸭子都会飞、会叫。所以继承不是正确的方法。可是尽管上面的使用Flyable接口的方法,能够解决部分问题(不再有会飞的橡皮鸭子),可是这个解决方式却彻底破坏了重用,它带来了还有一个维护的噩梦!

    甚至,在会飞的鸭子中。飞行的动作可能还有多种变化......。

         呵呵,假设是你你会怎么办?

          细致思考一下,由于鸭子的行为会在子类里不断的改变,Flyable接口攻克了仅仅有会飞的鸭子才实现Flyable接口。可是这样的方法无法达到代码复用。这就须要我们的第一个设计原则“分开变化和不会变化的部分”。

          我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变。

    我们须要做的就是把fly()quack()行为从Duck基类里隔离出来。我们希望一切能有弹性,可以指定行为到鸭子实类。比如:我们可能想要实例化一个新的野鸭实例,而且给它初始化一个特殊类型的飞行行为(飞行能力比較强)。换句话说,我们应该在鸭子类中包括设定行为的方法,这样就行在“执行时”动态的“改变”野鸭子的飞行行为。有了这种目标。看看第二条设计原则“针对接口编程。而不是针对实现编程”。

           ”针对接口编程“。关键就在于多态。利用多态,程序能够针对超类编程。运行时会依据实际情况运行到真正的行为,不会被绑死在超类的行为上。

           依据面向接口编程的设计原则,我们应该用接口来隔离鸭子问题中变化的部分,也就是鸭子的不稳定的行为(fly()quack())。我们要用一个FlyBehavior接口表示鸭子的飞行行为,QuackBehavior接口表示鸭子的叫声行为。如以下的类图:


              这种设计。能够让飞行和呱呱叫的行为被其它的对象复用。由于这些行为已经于鸭子类无关了。

    二我们能够新增一些行为。不会影响到既有的行为类,也不会影响“使用”到飞行行为类的鸭子类。

            说的有点多。接下来来实现这样的设计:

             1.在Duck类中增加两个实例变量,各自是“FlyBehavior”与“QuackBehavior”。每一个鸭子对象都将会动态的设置这些变量,以在执行时引用正确的行为类型。

         2.我们还要把fly()quack()方法从Duck类里移除,由于我们已经把这些行为到FlyBehaviorQuackBehavior接口里了。

         3.在鸭子的超类中设定SetQuackBehavior()SetFlyBehavior()那么就能够在执行时动态改变鸭子的行为了。

    具体设计类图


     源代码 

     http://download.csdn.net/detail/allen_gang/7492871

    參考Head First Design Patterns

  • 相关阅读:
    yii2.0 composer安装
    php composer包管理器
    Eclipse-selenium环境搭建
    JMeter-分布式
    Jmeter-接口压力测试
    Jmeter-操作Mysql
    Jmeter参数化-关联参数
    Jmeter参数化-从文件中读取参数(CSV Data Set Config)
    Jmeter参数化-用户参数
    Jmeter-文件上传
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6906895.html
Copyright © 2011-2022 走看看