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

23种设计模式——策略模式:像换口红一样切换你的算法

💄 策略模式:像换口红一样切换你的算法 💋

“算法千变万化,我自优雅应对” —— 解锁策略模式的美学智慧

🌟 策略模式:程序界的百变女王

想象你的代码是一位时尚达人:

  • 出门约会涂斩男色唇釉 💋
  • 商务会议用豆沙色口红 👠
  • 周末派对选姨妈色唇膏 🎉
  • 妆容核心始终不变!

策略模式正是这种智慧:

  • 定义算法家族:每种妆容策略
  • 封装每个算法:独立的口红颜色
  • 运行时自由切换:根据场景变换妆容
  • 核心逻辑不变:化妆流程始终如一
客户端
Context 化妆师
策略接口
斩男色策略
豆沙色策略
姨妈色策略

💡 为什么需要策略模式?

传统做法:if-else灾难

public void applyMakeup(String occasion) {if ("date".equals(occasion)) {// 50行斩男色代码} else if ("meeting".equals(occasion)) {// 50行豆沙色代码} else if ("party".equals(occasion)) {// 50行姨妈色代码}// 添加新场合?继续堆if-else!
}

痛点

  • 代码臃肿如塞爆的化妆包 💄
  • 添加新策略需修改核心类
  • 难以复用独立算法

策略模式:优雅解决方案

// 策略接口
interface LipstickStrategy {void applyColor();
}// 具体策略
class DateRedStrategy implements LipstickStrategy {public void applyColor() {System.out.println("👩‍❤️‍💋‍👨 涂抹斩男色:柔雾玫瑰调");}
}class MeetingStrategy implements LipstickStrategy {public void applyColor() {System.out.println("💼 轻点豆沙色:知性裸妆感");}
}// 上下文 - 化妆师
class MakeupArtist {private LipstickStrategy strategy;public void setStrategy(LipstickStrategy strategy) {this.strategy = strategy;}public void executeMakeup() {strategy.applyColor();System.out.println("✨ 完成精致唇妆");}
}// 客户端
public class Client {public static void main(String[] args) {MakeupArtist artist = new MakeupArtist();artist.setStrategy(new DateRedStrategy());artist.executeMakeup();artist.setStrategy(new MeetingStrategy());artist.executeMakeup();}
}

✨ 策略模式的四大魅力点

1. 开闭原则的典范

  • ✅ 新增策略零修改现有代码
  • ✅ 像口红盒添加新色号般自然

2. 消灭条件判断

  • 🚫 告别switch-case/if-else
  • 🎨 每种算法独立封装

3. 运行时动态切换

  • 🔄 程序运行中自由更换策略
  • ⏱️ 根据实时场景智能选择

4. 算法复用最大化

  • 📦 策略可跨场景复用
  • 🧩 如模块化彩妆盘自由组合

💻 真实场景:电商促销策略

// 促销策略接口
interface DiscountStrategy {double applyDiscount(double price);
}// 具体策略
class ChristmasDiscount implements DiscountStrategy {public double applyDiscount(double price) {return price * 0.6; // 圣诞6折}
}class MemberDiscount implements DiscountStrategy {public double applyDiscount(double price) {return price * 0.8; // 会员8折}
}// 支付上下文
class PaymentProcessor {private DiscountStrategy strategy;public void setStrategy(DiscountStrategy strategy) {this.strategy = strategy;}public double checkout(double originalPrice) {return strategy.applyDiscount(originalPrice);}
}// 使用示例
public class EcommerceDemo {public static void main(String[] args) {PaymentProcessor processor = new PaymentProcessor();// 圣诞促销processor.setStrategy(new ChristmasDiscount());System.out.println("圣诞价: $" + processor.checkout(100));// 会员促销processor.setStrategy(new MemberDiscount());System.out.println("会员价: $" + processor.checkout(100));}
}

📚 策略模式 vs 状态模式

特性策略模式状态模式
目的算法替换状态驱动行为改变
变化频率客户端主动切换状态自动转换
关系策略相互独立状态彼此知晓
类比主动选择口红颜色自动转换心情妆容

💼 策略模式面试宝典

Q1:策略模式适用哪些场景?

满分回答

"策略模式特别适合:

  1. 多种算法变体需要动态切换
  2. 需要消除大量条件语句
  3. 算法需要独立复用和扩展
    经典案例:
  • 电商促销折扣策略
  • 导航系统的路径算法
  • 支付网关的支付方式
  • 压缩工具的文件格式处理"

Q2:策略模式有哪些缺点?

专业回答

"需要注意三点:

  1. 客户端需了解策略差异:用户必须知道不同策略的区别
  2. 策略类数量膨胀:每个算法一个类可能产生大量小类
  3. 通信开销:策略与上下文间可能需要传递额外数据
    解决方案:
  • 用工厂模式封装策略创建
  • 合理使用组合减少类数量
  • 精心设计上下文接口"

Q3:策略模式如何提升代码质量?

高阶回答

"策略模式通过:

  1. 提高内聚:每个策略专注单一算法
  2. 降低耦合:上下文不依赖具体实现
  3. 增强扩展:符合开闭原则
  4. 简化测试:每个策略可独立测试
    在Spring中,常用@Qualifier注入不同策略实现"

🧩 设计挑战:旅行路线规划

interface RouteStrategy {void calculateRoute(Point start, Point end);
}class DrivingStrategy implements RouteStrategy {public void calculateRoute(Point start, Point end) {System.out.println("🚗 计算驾车路线:避开拥堵路段");}
}class WalkingStrategy implements RouteStrategy {public void calculateRoute(Point start, Point end) {System.out.println("🚶 生成步行路线:优先林荫小道");}
}class PublicTransportStrategy implements RouteStrategy {public void calculateRoute(Point start, Point end) {System.out.println("🚇 规划公交路线:最少换乘方案");}
}// 任务:实现RoutePlanner上下文类,支持动态切换策略
// 并添加骑行策略(BikingStrategy)

挑战提示

  1. 创建RoutePlanner类持有策略引用
  2. 实现设置策略的方法
  3. 添加执行路线规划的方法
  4. 实现BikingStrategy新策略

💄 美妆启示:策略模式精髓

就像精致妆容需要:

  • 基础打底:策略接口统一规范
  • 色彩选择:具体策略实现变化
  • 工具应用:上下文执行环境

在这里插入图片描述

🌈 总结:优雅应对变化之道

记住策略模式的时尚法则:

  1. 分离变与不变:算法可变,调用方式不变
  2. 拥抱扩展:新策略如新口红般即插即用
  3. 动态切换:运行时自由更换策略
  4. 拒绝臃肿:消灭条件判断语句

程序员美妆箴言:当你的代码需要应对多种"妆容"变化时,策略模式就是最优雅的化妆包!💄✨

http://www.lqws.cn/news/558595.html

相关文章:

  • Learning to Prompt for Continual Learning
  • 数据结构与算法 --- 双向链表
  • 问卷标记语言(QML):简化调查问卷设计与部署的XML解决方案
  • 【YOLOv13保姆级教程#03】自建数据集训练与验证(Train Val)全流程 | 手把手教你构建数据集、标签格式转换与yaml配置
  • Go开发工程师-Golang基础知识篇
  • Vue工程化实现约定式路由自动注册
  • 使用vue3构建一套网站
  • TCP 和 UDP 是什么?
  • 【Python基础】06 实战:视频压缩迷你脚本设计
  • 深入理解C#委托操作:添加、移除与调用全解析
  • 港澳地区,海外服务器ping通可能是地区运营商问题
  • MySQL为什么要使用b+树
  • 1 Studying《Computer Architecture A Quantitative Approach》1-4
  • 鸿蒙HarmonyOS 5小游戏实践:数字记忆挑战(附:源代码)
  • 信号处理学习——文献精读与code复现之TFN——嵌入时频变换的可解释神经网络(下)
  • 给定一个整型矩阵map,求最大的矩形区域为1的数量
  • Insar 相位展开真实的数据集的生成与下载(随机矩阵放大,zernike 仿真包裹相位)
  • Launcher3中的CellLayout 和ShortcutAndWidgetContainer 的联系和各自职责
  • 剑指offer50_0到n-1中缺失的数字
  • python -日期与天数的转换
  • autoas/as 工程的RTE静态消息总线实现与端口数据交换机制详解
  • 解决flash-attn安装报错的问题
  • 【C】陷波滤波器
  • 鸿蒙开发:资讯项目实战之底部导航封装
  • MySQL之MVCC实现原理深度解析
  • 类和对象(中)
  • springboot+Vue驾校管理系统
  • 开疆智能ModbusTCP转CClinkIE网关连接台达DVP-ES3 PLC配置案例
  • Java-正则表达式
  • 测量 Linux 中进程上下文切换需要的时间