设计模式---策略模式

目录

一、什么是策略模式

二、策略模式的结构

三、策略模式的角色和职责

Strategy

ConcreteStrategy

Context

四、策略模式的优缺点

五、示例代码

六、理解策略模式

认识策略模式

1.策略模式功能

2.策略模式和if-else语句

3.算法的平等性

4.谁选择具体的策略算法

5.Strategy的实现方式

6.运行时策略的唯一性

Context和Strategy的关系

比较两种扩展方式

1.扩展上下文的方式

2.在策略算法的实现上添加自己需要的数据的方式

容错恢复机制

策略模式结合模板方法模式

七、思考策略模式

本质

设计原则

何时选用


一、什么是策略模式

Strategy模式也叫策略模式是行为模式之一, 它对一系列的算法加以封装,为所有算法定义一 个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。Strategy模式主要用来平滑地处理算法的切换 。

定义一系列的算法,把他们一个个封装起来,并且使他们可以互相替换。

二、策略模式的结构

三、策略模式的角色和职责

Strategy

策略(算法)抽象。用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法

ConcreteStrategy

各种策略(算法)的具体实现。

Context

上下文,策略的外部封装类,或者说策略的容器类。负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类回调上下文的方法

四、策略模式的优缺点

1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。

2. 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。 决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻 辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或 行为变得不可能。

3. 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点

1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

2. 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

3.适合扁平的算法结构

五、示例代码

package strategy;

/**
 * @Author: ZhangLu
 * @Date: 2019/10/12 09:53
 * @Description: 策略,定义算法的接口
 */
public interface Strategy {

    /**
     * 某个算法的接口,可以有参数传入,也可以有返回值
     */
    void algorithmInterface();

}
package strategy;

/**
 * @Author: ZhangLu
 * @Date: 2019/10/12 10:05
 * @Description: 具体的算法实现
 */
public class ConcreteStrategyA implements Strategy{

    @Override
    public void algorithmInterface() {

    }
}
package strategy;

/**
 * @Author: ZhangLu
 * @Date: 2019/10/12 10:05
 * @Description:
 */
public class ConcreteStrategyB implements Strategy{
    @Override
    public void algorithmInterface() {

    }
}
package strategy;

/**
 * @Author: ZhangLu
 * @Date: 2019/10/12 10:05
 * @Description: 上下文对象,通常会持有一个具体的策略对象
 */
public class Context {

    /**
     * 持有一个具体的策略对象
     */
    private Strategy strategy;

    /**
     * 构造方法传如一个具体的策略对象
     * @param strategy 具体的策略对象
     */
    public Context(Strategy strategy){
        this.strategy = strategy;
    }

    /**
     * 上下文对客户端提供的操作接口,可以有参数和返回值
     */
    public void ContextInterface(){
        /**
         * 通常会转调具体的策略对象进行算法运算
         */
        strategy.algorithmInterface();
    }
}

六、理解策略模式

认识策略模式

1.策略模式功能

把具体的算法实现,从具体的业务处理里面独立出来,实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以互相替换。

重心不是如何来实现算法,而是如何组织,调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

2.策略模式和if-else语句

每个策略算法具体实现的功能,就是可以在if-else结构中的具体实现,if和else里的实现从运行地位上来说就是平等的。

策略模式就是把各个平等的具体实现封装到单独的策略实现类了,然后通过上下文来与具体的策略类进行交互。

3.算法的平等性

策略模式一个特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是一样的,正是因为平等性,才能实现算法之间的互相替换。所有的算法在实现上也是互相独立的,互相之间是没有依赖的。

策略算法是相同行为的不同实现。

4.谁选择具体的策略算法

一是在客户端,在使用上下文的时候,由客户端来选择具体的策略算法,然后把这个策略算法设置给上下文。

另一个是客户端不管,由上下文来选择具体的策略算法。

5.Strategy的实现方式

Strategy可以使用接口来定义,但是如果多个算法具有公共功能的话,可以设计为抽象类,把公共功能实现到Strategy中去。

6.运行时策略的唯一性

运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态的在不同的策略实现中切换,但是同时只能使用一个

Context和Strategy的关系

在策略模式中,通常是上下文使用具体的策略实现对象,反过来,策略实现对象也可以从上下文中获取所需要的数据,因此可以将上下文当作参数传递给策略实现对象,这种情况下上下文和策略实现对象是紧密耦合的。

这种情况下,上下文封装着具体策略对象进行算法运算所需要的数据,具体策略对象通过回调上下文的方法来获取这些数据。

甚至在某些情况下,策略实现对象还可以回调上下文的方法来实现一定的功能,这种使用场景下,上下文变相充当了多个策略算法实现的公共接口,在上下文定义的方法可以当作是所有或者部分策略算法使用的公共功能。

比较两种扩展方式

1.扩展上下文的方式

这样实现,所有策略的实现风格更统一,策略需要的数据都统一从上下文来获取,这样在使用方法上也很统一;另外,在上下文中添加新的数据,别的相应算法也用得上,可以视为公共数据。

但是,如果这些数据只有一个特定的算法来使用,那么这些数据有些浪费;另外每次添加新的算法都要扩展上下文,容易形成复杂的上下文对象层次。

2.在策略算法的实现上添加自己需要的数据的方式

这样实现比较简单,但是跟其他策略实现的风格不一致,其他策略都是从上下文中来获取数据,而该策略实现一部分数据来自上下文,一部分数据来自自己,不统一;另外,外部使用策略算法的时候也不一致,不太好以一个统一的方式来动态切换策略算法。

容错恢复机制

程序运行的时候,正常情况下应该按照某种方式来做,如果按照某种方式发生错误,系统不会崩溃,也不会就此不能继续向下运行,而是有容忍出错的能力,不但能容忍程序运行出现错误,还提供出现错误后的备用方案,也就是恢复机制,来代替正常执行的功能,是程序继续向下运行。

策略模式结合模板方法模式

在实际应用中,经常会出现一系列算法的实现上存在公共功能,甚至一系列算法的实现步骤都是一样的,只是在某些局部步骤上有所不同,这个时候,就可以对策略模式进行变形使用。

对于公共功能,有几种实现方式:

1.在上下文当中实现公共功能,让所有具体的策略算法回调这些方法

2.策略接口改成抽象类,在里面实现公共功能

3.给所有的抽象算法定义一个抽象的父类,让父类去实现策略接口,然后在这个父类l里去实现公共功能

如果发现”一系列算法的实现步骤都是一样的,只是在某些局部步骤上有所不同“的情况,那就可以在抽象类里定义算法实现的骨架,然后让具体的策略算法去实现变化的部分。这样的一个结构自然就变成策略模式结合模板方法模式,抽象类就是模板方法的模板类。

七、思考策略模式

本质

分离算法,选择实现

设计原则

1.开闭原则:通过把一系列可变算法进行封装,并定义出合理的使用结构,使得在系统出现新算法的时候,很容易把新算法加入到已有系统中,而已有实现不需要做修改。

2.里氏替换原则:策略模式是一个扁平结构,一系列的算法是兄弟关系,都是实现一个接口或继承一个父类。这样只要使用策略的客户保持面向抽象编程,就可以使用不同策略的具体实现对象来配置,实现一系列算法的互相替换。

何时选用

1.出现许多相关的类,仅仅是行为有差别的情况,可以使用策略模式来使用多个行为中的一个来配置一个类的方法,实现算法动态切换

2.出现同一个算法,有很多不同的实现的情况,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次

3.需要封装算法中,与算法相关的数据的情况,可以使用策略模式来避免暴露这些跟算法相关的数据结构

4.出现抽象一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况,可以使用策略模式来代替这些条件语句

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值