《告别 if-else 迷宫:Python 策略模式 (Strategy Pattern) 的优雅之道》

《告别 if-else 迷宫:Python 策略模式 (Strategy Pattern) 的优雅之道》

大家好,我是你的朋友,一位与 Python 代码相伴多年的开发者。在我们的编程生涯中,几乎都曾与一种“代码怪兽”搏斗过,它就是那冗长、复杂、牵一发而动全身的 if-elif-else 结构。

每当一个新的需求传来——“我们需要增加一种新的导出格式”,“能否支持另一种支付方式?”——我们就不得不硬着头皮,回到那个巨大的条件判断语句中,小心翼翼地添加一个 elif 分支。代码变得越来越臃肿,逻辑越来越混乱,每一次修改都像是在雷区排雷。

这违背了软件设计中一条至关重要的原则——开闭原则(Open/Closed Principle):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

那么,如何才能打破这个僵局,写出既能满足当前需求,又能从容应对未来变化的代码呢?今天,我将为你隆重介绍一位“拆弹专家”——策略模式(Strategy Pattern)

在这篇文章中,我们将一起:

  • 直面 if-else 的痛点,理解为什么它会成为代码质量的瓶颈。
  • 深入掌握策略模式的精髓,学习如何将多变的行为封装成可互换的“策略”。
  • 探索从经典实现到 Pythonic 风格的演进,看看 Python 的语言特性如何让这个模式焕发新生。
  • 通过真实案例,将策略模式应用到电商、数据处理等场景,感受其带来的灵活性与扩展性。

准备好告别纠缠不清的条件判断,开启一段代码重构的优雅之旅了吗?让我们开始吧!

第一部分:策略模式的核心思想——“各司其职,按需切换”

策略模式是一种行为设计模式,它定义了一系列算法(策略),并将每一个算法封装起来,使它们可以相互替换。此模式让算法的变化独立于使用算法的客户端。

听起来有点抽象?让我们用一个生活中的例子来理解它:出行旅游

假设你要从家(起点)去一个旅游景点(终点)。你有多种出行策略可供选择:

  • 策略 A:步行(WalkingStrategy
  • 策略 B:骑行(BikingStrategy
  • 策略 C:驾车(DrivingStrategy

作为“出行者”(我们称之为 上下文 Context),你并不需要关心每种方式的具体细节(如何走路,如何开车)。你只需要根据当前情况(天气、距离、预算),选择一个合适的策略,然后执行“出发”这个动作即可。

策略模式的三个关键角色:

  1. 上下文 (Context): 维护一个对策略对象的引用。它不执行具体的算法,而是将工作委托给当前的策略对象。在我们的例子中,就是“出行者” Navigator
  2. 策略接口 (Strategy Interface): 定义所有支持的算法的通用接口。在 Python 中,这通常是一个抽象基类(ABC)或一个简单的约定。例如,所有出行策略都有一个 route() 方法。
  3. 具体策略 (Concrete Strategy): 实现策略接口的具体算法。例如,WalkingStrategyBikingStrategy 等。

示意图

+-----------+            +------------------+
|  Context  | <>-------- |    IStrategy     |
| (Navigator)|           | (ABC with route())|
+-----------+            +------------------+^|+-----------------+-----------------+|                 |                 |
+-------------------+ +------------------+ +-------------------+
| ConcreteStrategyA | |ConcreteStrategyB | | ConcreteStrategyC |
| (WalkingStrategy) | | (BikingStrategy) | | (DrivingStrategy) |
+-------------------+ +------------------+ +-------------------+
从零开始的经典实现

让我们用代码来实现上述的出行导航场景。

from abc import ABC, abstractmethod# --- 策略接口 ---
class RouteStrategy(ABC):@abstractmethoddef build_route(self, start, end):pass# --- 具体策略 ---
class WalkingStrategy(RouteStrategy):def build_route(self, start, end):print(f"Building walking route from {start} to {end}: Go straight for 500m, turn right...")class BikingStrategy(RouteStrategy):def build_route(self, start, end):print(f"Building biking route from {start} to {end}: Follow the bike lane on Main St..."</

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919166.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis--day7--黑马点评--优惠券秒杀

&#xff08;以下内容全部来自上述课程&#xff09;优惠券秒杀 1. 全局唯一ID 每个店铺都可以发布优惠券:当用户抢购时&#xff0c;就会生成订单并保存到tb voucher order这张表中&#xff0c;而订单表如果使用数据库自增ID就存在一些问题: id的规律性太明显受单表数据量的限制…

Vue 与 React 深度对比:设计哲学、技术差异与应用场景

一、核心设计理念对比 特性 Vue React 设计目标 渐进式框架,降低学习曲线 构建大型应用,保持灵活性 设计哲学 “约定优于配置” “配置优于约定” 核心思想 响应式数据绑定 函数式编程 + 虚拟DOM 模板语言 HTML-based 模板 JSX(JavaScript XML) 状态管理 内置响应式系统 依…

软件开发 - foreground 与 background

foreground 与 background 1、foreground词性含义n.前景&#xff1b;最突出的位置.v使突出&#xff1b;强调# 例词in the 【foreground】&#xff08;在最显眼的位置&#xff09;【foreground】 task&#xff08;前台任务&#xff09;【foreground】 color&#xff08;前景色&a…

深度学习——03 神经网络(2)-损失函数

2 损失函数 2.1 概述作用&#xff1a;衡量模型预测结果&#xff08;y^\hat{y}y^​&#xff09;和真实标签&#xff08;yyy&#xff09;的差异&#xff0c;差异越大&#xff0c;说明模型参数“质量越差”&#xff08;需要调整&#xff09;&#xff1b;本质&#xff1a;深度学习训…

【大模型微调系列-04】 神经网络基础与小项目实战

【大模型微调系列-04】 神经网络基础与小项目实战&#x1f4a1; 本章目标&#xff1a;通过构建一个能识别手写数字的AI模型&#xff0c;让你真正理解神经网络是如何"学习"的。2-3小时后&#xff0c;你将拥有第一个自己训练的AI模型&#xff01;4.1 理论讲解&#xff…

JavaWeb前端(HTML,CSS具体案例)

前言 一直在学习B站黑马程序员苍穹外卖。现在已经学的差不多了&#xff0c;但是我学习一直是针对后端开发的&#xff0c;前端也没太注重去学&#xff08;他大部分都给课程资料嘻嘻&#x1f92a;&#xff09;&#xff0c;但我还是比较感兴趣&#xff0c;准备先把之前学JavaWeb&…

核心数据结构:DataFrame

3.3.1 创建与访问什么是 DataFrame&#xff1f;DataFrame 是 Pandas 中的核心数据结构之一&#xff0c;多行多列表格数据&#xff0c;类似于 Excel 表格 或 SQL 查询结果。它是一个 二维表格结构&#xff0c;具有行索引&#xff08;index&#xff09;和列标签&#xff08;colu…

深入探索Go语言标准库 net 包中的 IP 处理

深入探索Go语言标准库 net 包中的 IP 处理 文章目录深入探索Go语言标准库 net 包中的 IP 处理引言核心知识type IP常用函数常用方法代码示例常见问题1. DNS 查询失败怎么办&#xff1f;2. 如何区分 IPv4 和 IPv6 地址&#xff1f;使用场景1. 服务器端编程2. 网络监控和调试3. 防…

2.4 双向链表

目录 引入 结构定义 结构操作 初始化 插入 删除 打印 查找 随机位置插入 随机位置删除 销毁 总结 数据结构专栏https://blog.csdn.net/xyl6716/category_13002640.html 精益求精 追求卓越 【代码仓库】&#xff1a;Code Is Here 【合作】 &#xff1a;apollomona…

开发指南132-DOM的宽度、高度属性

宽度、高度类似。这里以高度为例来说明DOM中有关高度的概念&#xff1a;1、height取法&#xff1a;element.style.height说明&#xff1a;元素内容区域的高度&#xff0c;不含padding、border、margin该属性可写2、clientHeight取法&#xff1a;element..clientHeight&#xff…

魔改chromium源码——解除 iframe 的同源策略

在进行以下操作之前,请确保已完成之前文章中提到的 源码拉取及编译 部分。 如果已顺利完成相关配置,即可继续执行后续操作。 同源策略限制了不同源(协议、域名、端口)的网页脚本访问彼此的资源。iframe 的跨域限制由 Blink 渲染引擎和 Chromium 的安全层共同实现。 咱们直…

在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo

摘要 现在几乎所有主流应用都支持“深色模式”和“浅色模式”切换&#xff0c;这已经成了用户习惯。鸿蒙&#xff08;HarmonyOS&#xff09;同样提供了两种模式&#xff08;dark / light&#xff09;&#xff0c;并且支持应用根据系统主题切换&#xff0c;或者应用内手动切换。…

Redux搭档Next.js的简明使用教程

Redux 是一个用于 JavaScript 应用的状态管理库&#xff0c;主要解决组件间共享状态和复杂状态逻辑的问题。当应用规模较大、组件层级较深或多个组件需要共享/修改同一状态时&#xff0c;Redux 可以提供可预测、可追踪的状态管理方式&#xff0c;避免状态在组件间混乱传递。Red…

SCAI采用公平发射机制成功登陆LetsBonk,60%代币供应量已锁仓

去中心化科学&#xff08;DeSci&#xff09;平台SCAI宣布&#xff0c;其代币已于今日以Fair Launch形式在LetsBonk.fun平台成功发射。为保障资金安全与透明&#xff0c;开发团队已将代币总量的60%进行锁仓&#xff0c;进一步提升社区信任与项目合规性。SCAI是一个专注于高质量科…

【Kubernetes系列】Kubernetes中的resources

博客目录1. limits&#xff08;资源上限&#xff09;2. requests&#xff08;资源请求&#xff09;关键区别其他注意事项示例场景在 Kubernetes (k8s) 中&#xff0c;resources 用于定义容器的资源请求&#xff08;requests&#xff09;和限制&#xff08;limits&#xff09;&a…

hadoop 前端yarn 8088端口查看任务执行情况

图中资源相关参数含义及简单分析思路&#xff1a; 基础资源抢占参数 Total Resource Preempted: <memory:62112, vCores:6> 含义&#xff1a;应用总共被抢占的资源量&#xff0c; memory:62112 表示累计被收回的内存&#xff08;单位通常是MB &#xff0c;结合Hadoop生态…

基于SpringBoot的个性化教育学习平台的设计与实现(源码+lw+部署文档+讲解等)

课题介绍在教育数字化转型与学习者需求差异化的背景下&#xff0c;传统学习平台 “统一内容、统一进度” 的模式已显局限。当前&#xff0c;平台多提供标准化课程资源&#xff0c;无法根据学习者年龄、基础、目标&#xff08;如升学、技能提升&#xff09;定制学习路径&#xf…

UE5多人MOBA+GAS 48、制作闪现技能

文章目录添加标签添加GA_Blink添加标签 CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Teleport)CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Cooldown)UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Blink_Teleport, "Ability.Blink.Teleport"…

Swift 实战:实现一个简化版的 Twitter(LeetCode 355)

文章目录摘要描述示例解决答案设计思路题解代码分析测试示例和结果时间复杂度空间复杂度总结摘要 在社交媒体平台里&#xff0c;推送机制是核心功能之一。比如你关注了某人&#xff0c;就希望在自己的时间线上能看到他们的最新消息&#xff0c;同时自己的消息也要能出现在别人…

在浏览器端使用 xml2js 遇到的报错及解决方法

在浏览器端使用 xml2js 遇到的报错及解决方法 一、引言 在前端开发过程中&#xff0c;我们常常需要处理 XML 数据。xml2js 是一个非常流行的用于将 XML 转换为 JavaScript 对象的库。然而&#xff0c;当我们在浏览器端使用它时&#xff0c;可能会遇到一些问题。本文将介绍在浏览…