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

几周前,我为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语句时。易于维护和扩展: 添加新行为只需创建新的策略类,无需修改现有代码。行为解耦: 将不同的行为隔离到不同的类中,提高代码模块化和灵活性。

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

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

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 22:42:29
下一篇 2025年12月9日 17:33:56

相关推荐

  • Aurelia 对 JavaScript 框架的全新诠释

    React、Next.js、Svelte 和 Angular 等 JavaScript 框架占据了当前开发领域的中心位置。这些都是优秀的工具,但您是否了解 Aurelia 2? 初识 Aurelia 时,我也感到陌生。然而,两年来的使用经历让我确信,它至少是最佳 JavaScript 框架之一,甚至…

    好文分享 2025年12月19日
    000
  • 我该怎么做:导出/导入?

    本文分享我个人在JavaScript模块导出/导入方面的经验和最佳实践,并非强制性规范。 模块导出 不推荐的做法: function foo(){}function bar(){}function other(){}export {foo,bar,other} 原因:这种方法需要手动维护导出列表,一…

    2025年12月19日
    000
  • 可维护性就是您所需要的

    优秀的技术文档如同优秀的软件一样,需要持续更新和迭代,以满足所有项目参与者的需求。理想的技术文档需在详尽性和简洁性之间取得平衡,既要涵盖所有必要细节,又要保持易于理解。 然而,随着项目演进,文档可能逐渐落后于实际情况。新增功能、代码重构都可能导致文档需要同步更新。因此,在文档编写过程中,可维护性至关…

    2025年12月19日
    000
  • JavaScript 片段可以节省您的编码时间

    JavaScript 功能强大,但重复编写代码费时费力。这十个实用的 JavaScript 代码片段能简化常见任务,显著提升您的开发效率。现在就开始学习吧! 判断元素是否在视口中 轻松判断元素是否可见: const isInViewport = (element) => { const rec…

    2025年12月19日
    000
  • 释放 Chrome DevTools 代码片段的强大功能

    chrome devtools 的代码片段面板:提升开发效率的隐藏利器 Chrome DevTools 的代码片段面板是一个功能强大的工具,却常常被开发者忽视。它允许开发者直接在浏览器中编写、保存和运行自定义 JavaScript 代码,无需启动本地开发环境,极大地简化了实验、调试和演示 JavaS…

    2025年12月19日
    000
  • Nodejs v:内置 TypeScript 支持终于来了

    node.js v23.6.0 重磅更新:原生支持 typescript!告别额外配置,直接运行 .ts 文件。 TypeScript 的重要性不言而喻,它为 JavaScript 增加了可选静态类型和高级特性(如接口、泛型和类型推断),成为大型 JavaScript 应用的业界标准。Node.js…

    2025年12月19日
    000
  • Docker 的开发:第 1 集

    本系列教程将探讨在软件开发中使用 Docker 的优势和实用技巧,重点关注 Ruby on Rails 和 React 项目。 我们不会讲解 Docker 的基础概念,建议您先阅读官方文档,再继续阅读本系列文章。 开发动机 以下经验或许能帮助您理解使用 Docker 的必要性。 以往,我的 Ruby…

    2025年12月19日
    000
  • 立即吸引用户:在 React SPA 中嵌入交互式演示

    如果一张图片胜过千言万语,那么一个交互式演示的价值……岂止百万? 您是否喜欢通过冗长的说明文字来了解应用程序的功能?可能不会。我不想为我的最新项目 Wanna 撰写过多的赘述。因此,我寻求了一种更具吸引力的解决方案:将我的应用程序嵌入到登录页面中,供用户直接体验! 这段 GIF 包含 263 帧,所…

    2025年12月19日
    000
  • 闭包到底是什么?(简单的 JS 定义)

    还记得我第一次工作面试吗?面试官让我解释闭包。那简直是一场噩梦,因为我当时不懂那些专业术语。但直觉上,我觉得自己理解了它的含义,即使无法言表。 面试结束后(剧透:我没被录用),我赶紧谷歌搜索闭包相关资料。第一个遇到的术语就是词法作用域——啥玩意儿? 别担心,词法作用域其实很简单! 让我们一步步深入了…

    2025年12月19日
    000
  • 代码异味 – 非命令式函数名称

    清晰的函数命名:避免歧义,提升代码可读性 简而言之:含糊不清的函数名会隐藏其功能,令读者困惑。请使用具有描述性、面向动作的名称。 问题 函数用途不明确认知负担增加上下文误导可读性降低协作困难功能隐藏 解决方案 使用面向动作的动词使用描述性名称反映函数目的避免通用术语提供有意义的上下文明确表达单一职责…

    2025年12月19日 好文分享
    000
  • 使用发票模板 Word 和收据制作工具轻松计费

    对于小型企业和自由职业者来说,管理发票和收据常常令人头疼。然而,借助Word发票模板和收据生成工具,您可以有效地简化财务流程,提升业务效率和专业形象。本文将探讨这些工具如何轻松实现计费,并提升您的业务水平。 为什么选择Word发票模板? Microsoft Word凭借其普及性和易用性,成为创建专业…

    2025年12月19日
    000
  • TanStack Router:5 年后 React 路由的未来

    高效的路由机制是现代Web应用的基石,它直接影响着用户导航体验的流畅度。在2025年的React路由生态中,TanStack Router凭借其灵活、高效、简洁的特点脱颖而出,成为备受瞩目的新一代解决方案。本文将深入探讨TanStack Router的优势,以及它为何被认为是React路由的未来。 …

    2025年12月19日
    000
  • JavaScript 中的异步和等待

    JavaScript异步编程简述 JavaScript是单线程语言,一次只能执行一个任务。为处理多个任务,特别是I/O操作(例如API请求或文件读取),JavaScript采用异步编程。这使得在等待耗时操作完成时,其他任务可以继续执行。 回调函数 最初,JavaScript异步任务通过回调函数处理。…

    2025年12月19日
    000
  • 渗透测试工具:加强您的网络安全

    网络安全评估:渗透测试工具的应用 在当今复杂的网络环境中,有效的安全评估至关重要。渗透测试工具扮演着关键角色,帮助识别和评估网络、系统和应用程序中的安全漏洞。这些工具模拟真实世界攻击,让组织能够在潜在威胁演变为严重安全事件之前有效地降低风险。 渗透测试工具概述 渗透测试工具是软件应用或框架,旨在发现…

    2025年12月19日
    000
  • Flappy Bird 的遗产:游戏的简单性的最佳介绍

    在手机游戏领域,《flappy bird》的横空出世和持久影响力是少有的成功案例。这款由越南开发者 nguyễn hà Đông 于2013年推出的游戏,几乎在一夜之间风靡全球。其极简的设计风格、简单的游戏机制以及出人意料的超高难度,吸引了数百万玩家的关注。尽管游戏生命周期短暂,《flappy bi…

    2025年12月19日
    000
  • 何时在 Nextjs 中使用 SSR 和 SSG

    服务器端渲染 (SSR) 和 静态站点生成 (SSG) 是 Next.js 提供的两种强大的页面渲染模式,选择哪种模式取决于您的应用需求。 SSR (服务器端渲染): SSR 在每次用户请求页面时,都会在服务器端动态生成 HTML。这意味着每次访问页面,服务器都会获取最新数据并渲染页面,然后将完整的…

    2025年12月19日
    000
  • React 中的状态管理探索现代解决方案

    高效的状态管理是构建可扩展、高性能 React 应用的关键。近年来,React 的状态管理方案不断演进,为开发者提供了强大的工具来处理本地和全局状态。2025 年,React 生态系统提供了多种选择,从 Redux 等成熟方案到 Zustand 和 Jotai 等新兴方法,本文将探讨当前流行的状态管…

    2025年12月19日
    000
  • 了解 React 中遗留的 Promise 抛出行为

    React 框架以其构建用户界面的强大功能和灵活性而闻名,Suspense 是其现代特性之一,它允许组件以优雅的方式处理异步数据。然而,React 中的“遗留 Promise 抛出行为”常常让开发者感到困惑。本文将深入剖析这一行为的含义、它与 React 渲染过程的交互方式,以及在使用并发特性时理解…

    2025年12月19日
    000
  • 测试用例:创建有效软件测试框架的指南

    软件测试的基石:构建健壮的测试用例 有效的软件测试流程离不开精心设计的测试用例。它们为验证软件应用是否满足功能和非功能需求提供了一种系统化、结构化的途径。本文将深入探讨测试用例的概念、重要性、创建方法以及管理策略。 什么是测试用例? 测试用例是一套完整的规范,包含测试条件、输入数据、操作步骤以及预期…

    2025年12月19日
    000
  • ServiceNow UI 生成器

    新年快乐,各位! 我知道大家最近都在好奇我的动向。通过云架构师考试后,我决定深入研究一下现在很火的Web界面构建工具:UI Builder! UI Builder是什么? UI Builder是一个用于创建和配置自定义工作区和门户页面的Web界面。它是Now Experience UI框架的一部分,…

    2025年12月19日 好文分享
    000

发表回复

登录后才能评论
关注微信