使用策略模式避免过度调节

几周前,我为globo player开发了一个解决方案,需要在运行时动态启用或禁用软件中的特定功能。这种需求通常用if-else或switch语句的嵌套来实现,但这种方法并非总是最佳选择。本文将介绍一种更优雅的解决方案,适用于各种编程场景。

最佳策略是什么?

想象一下,您到达一个陌生的目的地,需要从机场前往酒店。您可以选择骑自行车(最便宜但最慢)、乘坐公共汽车(价格适中,速度和安全性较好)或租车(最快但最贵)。

使用策略模式避免过度调节

关键在于,无论选择哪种交通方式,目标都是一样的:到达酒店。

这个比喻同样适用于软件开发。当多个流程旨在实现相同目标时,策略模式可以提供帮助。

无策略编程的困境

假设我们要开发一个银行系统,根据客户的账户类型(例如“活期”、“储蓄”或“高级”)计算费用。这些计算需要在运行时进行,因此需要一种机制来正确引导代码流程。

一种常见的做法是使用链式条件语句:

class Banco {  calcularTaxa(tipoConta, valor) {    if (tipoConta === "corrente") {      return valor * 0.02; // 2% de taxa    } else if (tipoConta === "poupanca") {      return valor * 0.01; // 1% de taxa    } else if (tipoConta === "premium") {      return valor * 0.005; // 0,5% de taxa    } else {      throw new Error("Tipo de conta não suportado.");    }  }}const banco = new Banco();const taxa = banco.calcularTaxa("corrente", 1000); // exemplo: R$1000console.log(`A taxa para sua conta é: R$${taxa}`);

登录后复制

这种方法在简单场景下有效,但如果银行需要添加更多账户类型呢?代码将变得难以维护:

calcularTaxa(tipoConta, valor) {  // ... (大量的if-else语句)...}

登录后复制

这种方法存在以下问题:

1. 可扩展性差: 每次添加新的账户类型,都需要修改calcularTaxa方法,导致代码膨胀和复杂化。

2. 高度耦合: 费率计算逻辑与calcularTaxa方法紧密耦合,修改一种账户类型的计算可能会影响其他账户类型。

3. 代码冗余: 每种账户类型都重复类似的代码片段(例如valor * taxa),违反了DRY原则(Don’t Repeat Yourself)。

策略模式的优雅解决方案

为了解决这些问题,我们可以将每种账户类型视为一个独立的实体,因为每种类型都有其独特的费率计算逻辑和潜在的未来行为。

与其创建一个包含所有计算逻辑的Banco类,不如为每种账户类型创建一个单独的类:

class ContaCorrente {  calcularTaxa(valor) {    return valor * 0.02; // 2% de taxa  }}class ContaPoupanca {  calcularTaxa(valor) {    return valor * 0.01; // 1% de taxa  }}class ContaPremium {  calcularTaxa(valor) {    return valor * 0.005; // 0,5% de taxa  }}

登录后复制

这样,每个计算都与特定的账户类型相关联。 账户类型的选择则通过以下方式实现:

使用策略模式避免过度调节

基于策略的解决方案架构。
class Banco {  constructor(conta) {    this.conta = conta;  }  setConta(conta) {    this.conta = conta;  }  calcularTaxa(valor) {    if (!this.conta) {      throw new Error("Nenhuma conta definida.");    }    return this.conta.calcularTaxa(valor);  }}

登录后复制

注意,我们不再使用链式条件语句,而是通过Banco类的构造函数传入账户对象(策略)。setConta方法允许在运行时选择账户类型。费率计算通过this.conta.calcularTaxa(valor)进行。

const banco = new Banco(new ContaCorrente());console.log(`Taxa para conta corrente: R$${banco.calcularTaxa(1000)}`); // R$20banco.setConta(new ContaPoupanca());console.log(`Taxa para conta poupança: R$${banco.calcularTaxa(1000)}`); // R$10banco.setConta(new ContaPremium());console.log(`Taxa para conta premium: R$${banco.calcularTaxa(1000)}`); // R$5

登录后复制

这种方法实现了更灵活、可扩展和低耦合的代码。

策略模式的适用场景

策略模式适用于需要在运行时改变算法或行为,且无需将执行代码与不同的条件或类型紧密耦合的情况。它尤其适用于算法或行为可能因上下文而异,且这些算法之间相互独立的场景。

何时使用策略模式

可变行为: 当系统的行为需要根据特定条件动态更改时。避免复杂的条件语句: 当决策逻辑依赖于大量的if-else或switch语句时。易于维护和扩展: 添加新行为只需创建新的策略类,无需修改现有代码。行为解耦: 将不同的行为隔离到不同的类中,提高代码模块化和灵活性。

通过策略模式,我们可以编写更清晰、模块化和灵活的代码,从而更容易维护和扩展系统。

以上就是使用策略模式避免过度调节的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2642860.html

(0)
上一篇 2025年3月7日 06:55:02
下一篇 2025年2月22日 14:54:15

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 我该怎么做:导出/导入?

    本文分享我个人在JavaScript模块导出/导入方面的经验和最佳实践,并非强制性规范。 模块导出 不推荐的做法: function foo(){}function bar(){}function other(){}export {foo,…

    2025年3月7日
    200
  • 如何编写简单的端点和函数

    一个月前,我加入了 karmanx,学习了从基础到高级函数及端点编写方法。我有幸参加了ankita mam的讲座,她讲解了简单和复杂函数的编写以及api调用的工作原理。本文将简要概述函数的思考和编写方法。 从上图可以看出,客户端向服务器请求…

    2025年3月7日
    200
  • JavaScript 提升

    JavaScript 中的变量和函数声明会发生“提升”(hoisting)。这意味着声明会被移动到作用域的顶部,即使它们在代码中实际出现的位置更靠后。但这只影响声明本身,而不影响赋值。 JavaScript 的提升分为两种类型: 函数提升 …

    2025年3月7日
    200
  • 我的 Nextjs 学习之旅:构建真实项目

    大家好!我将分享我的 Next.js 学习心得,并对比它与 React.js 的差异。目前我正处于学习阶段,并着手构建一些有趣的项目,希望能为其他学习者提供一些参考。 为何从 React 转向 Next.js? 我最初使用 React,但希…

    2025年3月7日
    200
  • 您知道《神奇宝贝》对网络可访问性做出了贡献吗?

    1997年12月16日,《神奇宝贝》第38集“电力兵Porygon”在日本播出,引发了一场意外事件。剧中,小智和皮卡丘与Porygon对战时产生的强烈闪光,导致700多名观众,大部分是儿童,出现不适需就医。 事件始末: 部分观众患有光敏性癫…

    2025年3月7日
    200
  • 在 React 和 React Native 中为正则表达式验证创建自定义输入

    表单验证是确保用户输入符合特定规范的关键步骤。本文将通过React和React Native中的正则表达式验证,构建可复用的自定义输入组件,并以电话号码、信用卡和CVC码为例进行说明。 目录 为什么需要自定义输入组件?开始之前自定义输入组件…

    2025年3月7日
    200
  • 蹄它

    代码来临 2024 年第 10 天 第 1 部分 初探恐惧,继而兴奋 我习惯于先快速浏览一遍,再仔细阅读。 今天,我看到: 网格以及看似路径的元素 我担心这会是另一个最短路径难题。 然后我读懂了题意。 松了口气……至少第一部分是这样。 我需…

    2025年3月7日
    200
  • “漏洞”真相:理解 JavaScript 的稀疏数组和意外行为

    最近在复习数据结构与算法,特别是排序算法时,遇到一个有趣的问题:如何生成长度为n的随机数组来测试排序算法?看似简单,但使用new Array(n)却引发了意想不到的结果。 通常我们会这样生成随机数组: function randomarra…

    2025年3月7日
    200
  • JavaScript 开发人员的基本设计模式:提高您的编码掌握程度

    七大JavaScript设计模式:编写更优秀代码的秘诀 在动态的软件开发领域,熟练掌握设计模式对于构建可扩展、易维护、高效的代码至关重要。无论项目规模大小,设计模式都能为常见问题提供行之有效的解决方案。本文将深入探讨七种JavaScript…

    2025年3月7日
    200
  • Shadow DOM 完美版:体验怪物的力量

    shadow dom:构建现代化、高性能web组件的关键 Shadow DOM是现代HTML引擎中一项令人振奋的特性,它能够更好地封装和保护组件的内部实现细节,从而提升代码的可维护性和整洁度。我们坚信其重要性,并将其作为构建JavaScri…

    2025年3月7日
    200

发表回复

登录后才能评论