• Java核心篇,二十三种设计模式(二十一),行为型——策略模式


    一、概念

    该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理

    二、成员角色

    • Context(环境类):环境角色,它决定采用哪种策略。在环境类中维持一个对抽象策略类的引用实例,是用来初始化并操作策略的上下文环境
    • Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法
    • ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理

    三、使用场景

    • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中
    • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句
    • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时
    • 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构
    • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为

    四、优缺点

    优点

    • 策略模式提供了对 “开闭原则” 的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为
    • 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到抽象策略类中,从而避免重复的代码
    • 策略模式提供了一种可以替换继承关系的办法。如果不使用策略模式而是通过继承,这样算法的使用就 和算法本身混在一起,不符合 “单一职责原则”,而且使用继承无法实现算法或行为在程序运行时的动态切 换。
    • 使用策略模式可以避免多重条件选择语句。多重条件选择语句是硬编码,不易维护
    • 策略模式提供了一种算法的复用机制,由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类

    缺点

    • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况
    • 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类
    • 无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况

    五、业务分析

    假如有一种简单的计算器,它仅支持加法和减法运算,而且只能有两个操作数;这种情况下,无论加法还是减法,他都是一种计算方式,在进行计算的时候,我们完全可以直接传入两个操作数和一种计算方式来让计算器自己根据计算方式采取对应的计算算法进行下一步计算

    六、代码实现

    Calculator

    1. package com.designer.strategy.Context;
    2. import com.designer.strategy.Strategy.Calculation;
    3. /**
    4. * Context(环境类):环境角色
    5. * 计算器
    6. */
    7. public class Calculator {
    8. private Calculation calculation;
    9. public void setCalculation(Calculation calculation) {
    10. this.calculation = calculation;
    11. }
    12. public Integer exec(Integer operateNum1, Integer operateNum2){
    13. return this.calculation.calculate(operateNum1, operateNum2);
    14. }
    15. }

    Calculation

    1. package com.designer.strategy.Strategy;
    2. /**
    3. * Strategy(抽象策略类)
    4. * 计算器中的某种计算操作
    5. */
    6. public interface Calculation {
    7. public abstract Integer calculate(Integer operateNum1, Integer operateNum2);
    8. }

    AddCalculation

    1. package com.designer.strategy.ConcreteStrategy;
    2. import com.designer.strategy.Strategy.Calculation;
    3. /**
    4. * ConcreteStrategy(具体策略类)
    5. * 计算器中的加法
    6. */
    7. public class AddCalculation implements Calculation {
    8. @Override
    9. public Integer calculate(Integer operateNum1, Integer operateNum2) {
    10. return operateNum1 + operateNum2;
    11. }
    12. }

    SubCalculation

    1. package com.designer.strategy.ConcreteStrategy;
    2. import com.designer.strategy.Strategy.Calculation;
    3. /**
    4. * ConcreteStrategy(具体策略类)
    5. * 计算器中的减法
    6. */
    7. public class SubCalculation implements Calculation {
    8. @Override
    9. public Integer calculate(Integer operateNum1, Integer operateNum2) {
    10. return operateNum1 - operateNum2;
    11. }
    12. }

    Test

    1. package com.designer.strategy;
    2. import com.designer.strategy.ConcreteStrategy.SubCalculation;
    3. import com.designer.strategy.Context.Calculator;
    4. import com.designer.strategy.Strategy.Calculation;
    5. public class Test {
    6. public static void main(String[] args) {
    7. // 定义一个计算器
    8. Calculator calculator = new Calculator();
    9. // 定义一种算法
    10. Calculation sub = new SubCalculation();
    11. // 利用上下文环境为计算机设置算法
    12. calculator.setCalculation(sub);
    13. // 计算 100 - 21
    14. Integer value = calculator.exec(100, 21);
    15. System.out.println(value);
    16. }
    17. }
  • 相关阅读:
    腾讯云cvm云硬盘扩容
    新零售项目及离线数仓核心面试,,220807,,
    VB实现长标题文本压缩
    ROS学习笔记08、机器人导航仿真(slam、map_server、amcl、move_base与导航消息介绍)
    Vue2源码学习笔记 - 14.响应式原理—核心本质
    leetcode(力扣):203移除链表元素 leetcode(力扣):206反转链表 leetcode(力扣):876.链表的中间结点多种解法
    WebRTC系列-网络传输之5选择最优connection切换
    中国为什么要发展人工智能
    lighttpd cgi不能重启
    dart的Websocket为什么找不到onOpen方法?
  • 原文地址:https://blog.csdn.net/ITlanyue/article/details/125460479