策略模式

来源:互联网 发布:java listnode遍历 编辑:程序博客网 时间:2024/05/29 06:29

策略模式

                             ----Head First 设计模式有感

策略模式的定义:定义了算法族,分别分装起来,让他们之间可以互相替换,此模式让算法的变化独立于算法的客户。

说明: http://images.cnblogs.com/cnblogs_com/colinsong/策略模式.gif

                                          1 策略模式图

 

Context(应用场景):

1.需要使用ConcretStrategy提供的算法;

2.内部维护一个Strategy的实例;

3.负责动态设置运行时Strategy的具体算法;

4.负责跟Strategy的数据传递和交互。

 

Strategy(抽象策略类):

1.定义了一个公共的借口,各种不同的算法以不同的方式实现该借口。Context使用不同的借口来调用不同的算法,一般使用借口或抽象类来实现。

 

ConcreteStrategy(具体策略类):

1.实现了Strategy定义的接口,提供了不同的算法实现。

 

应用场景:

1.多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。(例如FlyBehaviorQuackBehavior)

 

2.需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。(例如FlyBehaviorQuackBehavior的具体实现可任意变化或扩充)

 

3.对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。

 

优点:

1.提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)

 

2.避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。

 

3.遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

 

缺点:

 

1.因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

 

 

下面举一个鸭子应用的例子:

说明: http://images.cnblogs.com/cnblogs_com/justinw/str_62.jpg

       这是一个模拟鸭子游戏:SimuDuck。游戏中会出现各种鸭子,一边游泳戏水,一边咕咕嘎嘎叫。首先实现了一个鸭子的超(Duck),里面封装了swim()、PerformFly()、PerformQuack()、SetFlyBehavior()、SetQuackBehavior()、display()方法。

        Swim()方法顾名思义,所有的鸭子都会游泳,就由超类负责实现这部分的实现代码。SetFlyBehavior()、SetQuackBehavior()是鸭子的子类可以通过设定方法来设定鸭子的行为,而不是在鸭子的构造器内实例化。display()是展现鸭子的外观的方法。在Duck类中加入两个实例变量,分别为flyBehaviorquackBehavior,声明为借口类型,而不是具体实现类型,每个鸭子都会动态地设置这些变量以在运行时引用正确的行为类型。此处实现了OO设计的一个原则:多用组合,少用继承。这种使用接口实例变量的方法即为组合,它和继承不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象组合而来。

       我们鸭子的子类有绿头鸭、橡皮鸭、红头鸭,其中橡皮鸭是吱吱叫且不会飞,而绿头鸭和红头鸭除了外观不同,其他都一样,都会飞并且是呱呱叫。

       根据鸭子的子类我们将叫和飞这两种行为封装两个抽象类或接口中。为什么将行为单独从鸭子中抽出来而不是放在鸭子中呢?我们假设下,如果放在超类鸭子中,我们每个子类都会继承者两个方法,可是有的鸭子是会飞,而有些是不会飞的,如果我们在子类中覆盖着两个方法,不仅违背类OO设计的简介复用的原则,还造成了代码维护修改的麻烦。下面引入OO设计的一个原则:找出应用中可能需要的变化之处,把它们独立出来,不要和那些不需要变化的代码混合起来。所以我们设计了FlyBehaviorQuackBehavior这两个抽象策略类,而FlyWithWings(会飞)和FlyNoWay(不会飞)继承了FlyBehavior接口,Quack1(嘎嘎叫)、Quack2(吱吱叫)、Quack3(不会叫)继承了QuackBehavior接口,

 

以下是实现代码

原创粉丝点击