从零开始学设计模式(十六):策略模式(Strategy Pattern)

简介: 策略模式(Strategy Pattern)也被称为政策模式(Policy)。它指的是定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,算法的变化不会影响使用算法的客户。

定义


策略模式(Strategy Pattern)也被称为政策模式(Policy)。它指的是定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,算法的变化不会影响使用算法的客户。


策略模式通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。它属于对象行为模式。


可以这么理解:策略就是解决问题的办法。一个问题往往有很多种不同的解决办法,每一种办法就是一种策略了,就好比以前高中的时候解决数学问题,一个题目也可以有很多种解决办法,但是每个人都可以根据一定的因素或者条件来选择不同的策略解决问题。


组成部分


策略模式包含以下三个主要部分:


1、抽象策略类(Strategy):它主要定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。


2、具体策略类(Concrete Strategy):它主要就是继承了抽象策略类,并且提供具体的算法实现。


3、环境类(Context):也叫上下文,起承上启下封装作用,它持有一个策略类的引用,对策略进行二次封装,目的是屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。最终给客户端调用。


例子


上面的介绍完可能还是有点不太好理解,看一个简单的例子,就对策略模式有清晰的认识了。


首先定义一个抽象策略类,定义一个走路的抽象方法:


/**
 * @Author: 江夏
 * @Date: 2021/11/23/21:16
 * @Description:抽象策略类
 */
public abstract class Strategy {
    public abstract void run();
}
复制代码


接着定义两个具体的策略类继承抽象策略类,并且实现抽象的策略方法:


/**
 * @Author: 江夏
 * @Date: 2021/11/23/21:17
 * @Description:具体策略类1
 */
public class ConcreteStrategy1 extends Strategy {
    @Override
    public void run() {
        System.out.println("具体策略类ConcreteStrategy1跑着走");
    }
}
复制代码


/**
 * @Author: 江夏
 * @Date: 2021/11/23/21:17
 * @Description:具体策略类2
 */
public class ConcreteStrategy2 extends Strategy {
    @Override
    public void run() {
        System.out.println("具体策略类ConcreteStrategy2慢悠悠地走");
    }
}
复制代码


接着就是上下文context类:


/**
 * @Author: 江夏
 * @Date: 2021/11/23/21:18
 * @Description:上下文类
 */
public class Context {
    public Strategy strategy;
    //构造函数
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    public void process(){
        strategy.run();
    }
}
复制代码


最后再来一个测试方法:


/**
 * @Author: 江夏
 * @Date: 2021/11/23/21:20
 * @Description:测试方法
 */
public class StrategyPatternTest {
    public static void main(String[] args) {
        Context context = null;
        System.out.println("策略一");
        context = new Context(new ConcreteStrategy1());
        context.process();
        System.out.println("策略二");
        context = new Context(new ConcreteStrategy2());
        context.process();
    }
}
复制代码


运行结果如下:

f1acb86bba924791a25f7b0f170a6b34~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


看完了案例,可能会觉得这不是前一篇的模版方法模式吗?其实策略模式和模版方法模式很相似。


策略模式与模版方法模式的区别仅仅是多了一个单独的上下文类Context。在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了上下文Context类中,抽象策略类只是为了定义规范,里面一般不包含逻辑。策略模式中加了上下文类,通过上下类调用方法,屏蔽了直接对具体实现的访问,更符合面向对象的原则。


策略模式的优点


1、策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。


2、易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展,只需要新增一个类就可以了。


策略模式的缺点


1、策略模式易于拓展的后果就是维护各个策略类会给开发带来额外开销,每一个策略都是一个类,复用的可能性很小、类数量增多。


2、所有的策略类都需要对外暴露,因为使用哪种策略是由客户端来决定的。违背了迪米特法则。


应用场景


策略模式实质上就是面向对象中的继承和多态,使用策略模式的场景很多,而且在很多应用的场景中,在策略模式中一般会看到模版方法模式的影子,所以策略模式的应用场景和模版方法基本差不多,比如:


1、如果代码中几个类的主要逻辑相同,只在部分逻辑的算法和行为上有一些区别;


2、有几种相似的逻辑,但是需要由客户端动态地决定使用哪一种;


总结


策略模式是一种简单并且常用的模式,它主要就一个算法抽象类或者接口封装算法、然后多个具体的算法实现类实现它的方法再被一个上下文类来包装一下。一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。


本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star!

目录
相关文章
|
8天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
25 1
|
11天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
20 2
|
25天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
43 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
32 3
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
29 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
64 3
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
31 1
|
2月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第12天】 在软件开发的世界中,设计模式是解决常见问题的最佳实践。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理运用设计模式可以极大地提高代码的可维护性、扩展性和复用性。本文将深入探讨策略模式(Strategy Pattern)的原理、实现方式及其在PHP中的应用。通过具体示例,我们将展示如何利用策略模式来解耦算法与对象,从而让代码更加灵活和易于管理。
19 0
|
2月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 在PHP开发领域,设计模式是提升代码可维护性、扩展性和重用性的关键技术之一。本文聚焦于策略模式这一行为型设计模式,通过理论阐述与实例分析,揭示其在PHP应用程序中优化算法切换和业务逻辑解耦方面的强大效用。不同于常规摘要,本文不直接概述研究方法或结果,而是基于实际开发场景,探讨策略模式的应用价值和实现方式,旨在为PHP开发者提供一种高效应对复杂业务需求变化和技术债务累积问题的策略思维。