当前位置: 首页 > article >正文

【设计模式-行为型】策略模式

一、什么是策略模式

        要说策略模式,那么我脑袋里有一个例子,是一个策略模式使用的大家,那就是在周星驰的电影《国产凌凌漆》中的----达文西。

        达文西:“没错就是我,请叫我文西”。

        电影中,角色达文西以其机智和创造力,生动地展示了策略模式的精髓。面对电影中的反派角色金枪客的威胁,达文西,这位“聪明的发明家”,迅速设计并制造了一种应对紧急情况的策略武器——“要你命3000”。

        “要你命3000”是一种超级武器,它巧妙地将西瓜刀、铁链、火药、硫酸、毒药、手枪、手榴弹等十多种武器结合在一起,形成了一种看似强大但实际上荒谬的混合武器。达文西在剧中自豪地介绍他的发明:“要你命三千,西瓜刀,铁链,火药,硫酸,毒药,手枪,手榴弹,杀虫剂,每样都能独当一面,现在集中在一起,看你怕不怕?”这句话不仅展现了达文西的幽默感,也体现了策略模式的核心思想:通过组合不同的元素来应对特定的挑战。

        这个场景中的“要你命3000”就是策略模式的一个典型应用。策略模式允许我们在运行时根据不同的情况选择不同的算法或行为,就像达文西根据不同的威胁选择不同的武器一样。这种模式使得系统更加灵活,能够适应不断变化的需求。

策略模式的定义: 策略模式是一种行为设计模式,它定义了一系列算法(要你命3000),将每个算法封装起来(要你命3000中的每个武器),并使它们可以互换(可以使用每种武器应对金枪客)。

二、为什么用策略模式

那么我们可以根据这个示例,来讨论一下为什么要使用策略模式(为啥会想到用要你命3000):

  1. 算法多样性:在电影中,达文西面对不同的敌人和战斗场景,需要不同的武器。这就像在软件开发中,我们可能需要根据不同的输入或条件来选择不同的算法。策略模式允许我们在运行时选择最合适的算法。例子: 假设我们有一个支付系统,需要支持多种支付方式(现金、信用卡、移动支付等)。每种支付方式都是一个策略。通过策略模式,我们可以轻松地添加新的支付方式,而不需要修改现有的代码。

  2.  代码复用:达文西的“要你命3000”虽然是一个荒谬的发明,但它展示了如何将不同的工具组合起来以应对特定的挑战。在软件开发中,这意味着我们可以重用已有的算法,而不需要每次都重新编写代码。例子: 在图像处理软件中,我们可能有多种图像滤镜(如模糊、锐化、边缘检测等)。每种滤镜都是一个策略。通过策略模式,我们可以在不同的上下文中重用这些滤镜算法,而不需要为每个新功能重新编写代码。

  3. 简化切换:在电影中,达文西可能需要快速地从一种武器切换到另一种武器。在软件开发中,策略模式允许我们在运行时轻松地切换算法,而不需要复杂的条件判断。例子: 在游戏开发中,我们可能需要根据玩家的选择或游戏状态来切换不同的AI行为。通过策略模式,我们可以轻松地在不同的AI策略之间切换,以适应游戏的不同阶段或玩家的不同行为。

  4.  提高可读性:达文西的发明虽然荒诞,但它清晰地展示了如何将不同的元素组合起来。在软件开发中,策略模式通过将算法封装在独立的类中,提高了代码的可读性和可理解性。例子: 在文本编辑器中,我们可能有多种文本格式化策略(如加粗、斜体、下划线等)。通过策略模式,我们可以清晰地定义每种格式化策略,使得代码更加模块化和易于理解。

  5. 易于扩展:达文西的“要你命3000”展示了如何通过组合不同的元素来创造新的发明。在软件开发中,策略模式使得添加新的算法变得非常容易,而不需要修改现有的代码。例子: 在电子商务平台中,我们可能需要支持多种配送策略(如快递、平邮、同城配送等)。通过策略模式,我们可以轻松地添加新的配送策略,而不需要修改现有的订单处理代码。

  6. 解耦:达文西的发明展示了如何将不同的元素组合起来,而不需要它们之间有直接的依赖关系。在软件开发中,策略模式将算法的实现与使用算法的客户端解耦,提高了系统的灵活性。例子: 在数据库访问层中,我们可能需要支持多种数据库操作(如查询、更新、删除等)。通过策略模式,我们可以将数据库操作的实现与使用这些操作的业务逻辑解耦,使得数据库访问层更加灵活和可维护。

三、策略模式示例

        在代码中,我一般很少直接用策略模式,一般直接使用策略枚举:

  1. 武器策略接口(约束算法的行为):
    //武器策略接口
    public interface WeaponStrategy {
        void attack();
    }
  2. 武器的实现类(具体的算法):
    //西瓜刀武器策略
    public class WatermelonKnifeStrategy implements WeaponStrategy {
        @Override
        public void attack() {
            System.out.println("吃我一西瓜刀!");
        }
    }
    //链条武器策略
    public class ChainStrategy implements WeaponStrategy {
        @Override
        public void attack() {
            System.out.println("吃我一链条!");
        }
    }
    //火药武器策略
    public class GunpowderStrategy implements WeaponStrategy {
        @Override
        public void attack() {
            System.out.println("吃我一火药!");
        }
    }
  3. 武器组合(要你命3000):
    //武器库:枚举
    public enum BattleStrategyEnum {
        WATERMELON_KNIFE("watermelon_knife", new WatermelonKnifeStrategy()),
        CHAIN("chain", new ChainStrategy()),
        GUNPOWDER("gunpowder", new GunpowderStrategy());
    
        private final String key;
        private final WeaponStrategy strategy;
    
        BattleStrategyEnum(String key, WeaponStrategy strategy) {
            this.key = key;
            this.strategy = strategy;
        }
    
        public String getKey() {
            return key;
        }
    
        public WeaponStrategy getStrategy() {
            return strategy;
        }
    
        public static WeaponStrategy getStrategyByKey(String key) {
            for (BattleStrategyEnum strategy : BattleStrategyEnum.values()) {
                if (strategy.getKey().equals(key)) {
                    return strategy.getStrategy();
                }
            }
            throw new IllegalArgumentException("No strategy found for key: " + key);
        }
    }
  4. 达文西使用场景(根据传入的不同策略,执行对应的策略):
    public class BattleContext {
        private WeaponStrategy strategy;
    
        public BattleContext(String strategyKey) {
            this.strategy = BattleStrategyEnum.getStrategyByKey(strategyKey);
        }
    
        public void executeStrategy() {
            strategy.use();
        }
    }
  5. 场景(达文西大战金枪客)
    public class BattleSimulation {
        public static void main(String[] args) {
            // 模拟战斗场景
            System.out.println("Battle against Golden Gunman starts:");
            
            // 创建上下文对象
            BattleContext context;
    
            // 初期战斗策略
            context = new BattleContext(BattleStrategyEnum.WATERMELON_KNIFE.getKey());
            System.out.println("吃我一招:");
            context.executeStrategy();
            
            // 中期战斗策略
            context = new BattleContext(BattleStrategyEnum.CHAIN.getKey());
            System.out.println("再来一招:");
            context.executeStrategy();
            
            // 最终战斗策略
            context = new BattleContext(BattleStrategyEnum.GUNPOWDER.getKey());
            System.out.println("最后一招:");
            context.executeStrategy();
        }
    }


http://www.kler.cn/a/516384.html

相关文章:

  • C语言常用知识结构深入学习
  • HDFS的Shell操作
  • 63,【3】buuctf web Upload-Labs-Linux 1
  • vim练级攻略(精简版)
  • SSM开发(二) MyBatis简介
  • 计算机毕业设计hadoop+spark股票基金推荐系统 股票基金预测系统 股票基金可视化系统 股票基金数据分析 股票基金大数据 股票基金爬虫
  • 照片永久删除后的数据恢复全攻略
  • 100%全国产化时钟服务器、全国产化校时服务器、全国产化授时服务器
  • Docker Desktop 在Windows 环境中开发、测试和运行容器化的应用程序
  • JVM面试题解,垃圾回收之“垃圾回收器”剖析
  • pytest自动化测试 - pytest夹具的基本概念
  • 安全开发 JavaEE 反射机制 对象 成员变量 构造方法 成员方法 攻击链
  • HarmonyOS手势处理
  • 常见的备份服务器操作系统如何选择
  • 2025年数学建模美赛:A题分析(1)Testing Time: The Constant Wear On Stairs
  • C语言-运算符
  • 智慧冷库可视化监控系统
  • 服务器内部是如何运行的
  • 基于微信小程序的童装商城的设计与实现(LW+源码+讲解)
  • qml FileDialog 详解
  • 汇编与逆向(二)-汇编基础
  • 多管齐下以IP地址查询精度
  • 汇编实验·分支程序设计
  • fpga学习入门 串口rs232回环
  • 放大器版图绘制全流程
  • JavaScript系列(41)--状态管理实现详解