简化理解:策略设计模式

简介: 本篇带来另外一种设计模式介绍,你或许天天和它打交道,但是不认识它,它就是“策略模式”。


就在前不久,我们讲了创建对象的 3 种常见设计模式:工厂设计模式、构造函数设计模式、原型设计模式(蓦然回首,“工厂、构造、原型”设计模式,正在灯火阑珊处)。这 3 种设计模式,真切时刻发生在我们日常编码生活中,蓦然回首,灯火阑珊处。


本篇带来另外一种设计模式介绍,你或许天天和它打交道,但是不认识它,它就是“策略模式”。


策略模式就像诸葛亮的锦囊,它在代码中是这样体现的:


比方说,我们有一个销售活动,它有着不同的销售策略


function getPrice(originalPrice, status) {
  if (status === 'pre-sale') { // 预售打 8 折
    return originalPrice * 0.8
  }
  if (status === 'promotion') { // 促销打 9 折或者便宜 20
    if (origialPrice <= 100) {
      return origialPrice * 0.9
    } else {
      return originalPrice - 20
    }
  }
  if (status === 'black-friday') { // 周五有多种打折策略
    if (origialPrice >= 100 && originalPrice < 200) {
      return origialPrice - 20
    } else if (originalPrice >= 200) {
      return originalPrice - 50
    } else {
      return originalPrice * 0.8
    }
  }
  if (status === 'default') { // 默认不打折
    return originalPrice
  }
}


这样写,有无毛病?


老观众都知道:当然是有的,它违反了“开闭原则”和“单一职责原则”。(这两个原则经常提到,敲重点)


为啥违反“开闭原则”?因为当你要加入一个新的策略的时候,要修改 getPrice 函数内部代码,这不是我们提倡的,我们提倡:不频繁修改函数体内部,通过预留的扩展接口来增加功能;


即:修改函数内部 ⇒ no,拓展函数功能 ⇒ yes


为啥违法“单一职责”?因为 getPrice 函数负责的判断太多了,又是这又是那的,职责太多,都没有解耦;


还有一个更大的问题,当其中的一种策略代码报错,会影响到整个 getPrice 函数的向下执行。


基于以上的原因,于是乎,策略模式闪亮登场!!


function preSalePrice(origialPrice) { // 预售打 8 折
  return originalPrice * 0.8
}
function promotionPrice(origialPrice) { // 促销打 9 折或者便宜 20
  if (origialPrice <= 100) {
    return origialPrice * 0.9
  } else {
    return originalPrice - 20
  }
}
function blackFridayPrice(origialPrice) { // 周五有多种打折策略
  if (origialPrice >= 100 && originalPrice < 200) {
    return origialPrice - 20
  } else if (originalPrice >= 200) {
    return originalPrice - 50
  } else {
    return originalPrice * 0.8
  }
}
function defaultPrice(origialPrice) { // 默认不打折
  return origialPrice
}
let priceStrategies = { // 打折策略
  'pre-sale': preSalePrice,
  'promotion': promotionPrice,
  'black-friday': blackFridayPrice,
  'default': defaultPrice
}
function getPrice(originalPrice, status) { // 根据策略获取价格
  return priceStrategies[status](originalPrice)
}


优化后,代码从这样:

image.png


变成了这样:

image.png


图片来源


完美解决!!代码看起来更简洁、清晰。


如果你的代码有很多 if…else… 判断,各判断里的代码又相互独立,可考虑使用策略模式,封装各判断的代码,用 map 的方式,取出你的锦囊妙计吧

策略模式,就这,原来设计模式就在我们身边~~

参考:useful-design-patterns

作者:bytefish


相关文章
|
7月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
145 0
|
7月前
|
设计模式 编解码 C++
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(一)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
203 0
|
7月前
|
设计模式 存储 缓存
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(二)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
116 0
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
7月前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
128 2
|
4月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
58 1
|
5月前
|
设计模式 安全 Java
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
119 0
|
7月前
|
设计模式 Java
设计模式之策略 Strategy
设计模式之策略 Strategy
46 1
|
设计模式 算法 搜索推荐
设计模式—策略(Strategy)模式
设计模式—策略(Strategy)模式
154 1
|
7月前
|
设计模式 缓存 安全
分析设计模式对Java应用性能的影响,并提供优化策略
【4月更文挑战第7天】本文分析了7种常见设计模式对Java应用性能的影响及优化策略:单例模式可采用双重检查锁定、枚举实现或对象池优化;工厂方法和抽象工厂模式可通过对象池和缓存减少对象创建开销;建造者模式应减少构建步骤,简化复杂对象;原型模式优化克隆方法或使用序列化提高复制效率;适配器模式尽量减少使用,或合并多个适配器;观察者模式限制观察者数量并使用异步通知。设计模式需根据应用场景谨慎选用,兼顾代码质量和性能。
57 0