修复糟糕的代码气味

2024-04-12 16:52
文章标签 代码 修复 糟糕 气味

本文主要是介绍修复糟糕的代码气味,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

修复糟糕的代码气味

在这里插入图片描述

原文链接:https://www.arjancodes.com/blog/best-practices-for-eliminating-python-code-smells/

文章列举了多种糟糕的代码模式,并给出了解决方法。通过这些修改,可以使得代码更易读、更可维护。
这些糟糕的代码气味是:

  1. 万能对象:一个类具有太多的功能,违背了单一责任原则。这个类会变得复杂,难以测试和维护。 解决方法:根据任务拆分成多个类。
  2. 重复代码:相同的代码块多次出现,增加了冗余,并且增加维护难度。 解决方法:抽象出一个函数,通过调用函数替代多个相同的代码块。
  3. 过长的方法:一个方法太长,说明这个方法做了太多事情,理解和维护该方法会很困难。 解决方法: 按照功能,拆分成若干的方法。
  4. 神奇数字: 代码中出现的神秘数字难以理解和修改。解决方法:定义一个常量表示数字的含义。
  5. 嵌套过深:过多的嵌套使得函数的流程难以把握。 解决办法: 去掉嵌套条件,必要时创建函数。 利用内置的any, all 处理多个条件。

1. The “god object” smell (万能对象)

class OnlineStore:def search_product(self, query: Query):# Logic to search for products in some databasepassdef process_order(self, order: Order):# Logic to process the order and send confirmation emailpassdef handle_payment(self, payment_info: PaymentInfo):# Logic to handle payment and update the order statuspassdef manage_inventory(self, product_id: int, quantity: int):# Logic to manage inventory and update the databasepass# Many more methods

“上帝对象”是整体设计的,处理了太多的任务和责任,违反了SOLID设计的单一责任原则(SRP, Single Responsibility priciple)。代码示例中的 OnlineStore类负责库存管理、订单处理、付款接受和产品搜索。将所有这些职责合并到一个类别中可能会限制我们引入新功能的灵活性,同时增加测试和维护的复杂性。

我们可以将 OnlineStore 类重写为更易于管理的专用类(如 ProductSearch 、 OrderProcessor 、 PaymentGateway 和 InventoryManager )。这使得每个类在遵守 SRP 的同时专注于特定任务。

class ProductSearch:def search_product(self, query: Query):# Logic to search for products in some databasepassclass OrderProcessor:def process_order(self, order: Order):# Logic to process the order and send confirmation emailpassclass PaymentGateway:def handle_payment(self, total: int, payment_info: Payment):# Logic to handle payment and update the order statuspassclass InventoryManager:def manage_inventory(self, product_id: int, quantity: int):# Logic to manage inventory and update the databasepass

2. The “duplicate code” smell (重复代码)

class ReportGenerator:def generate_sales_report(self, sales_data: list[Report):# Preprocessing steps, such as formatting the data into a table.# Generate sales reportpassdef generate_inventory_report(self, inventory_data: list[Report]):# Preprocessing steps (duplicated)# Generate inventory reportpass

当相同的代码块多次出现时,它被视为重复代码。重复代码增加了冗余和不一致的可能。
我们可以将这些重复的过程组合成一个单一的方法来解决这个问题。通过这种方式,我们消除了冗余,并将其与 DRY(不要重复自己)编码理念保持一致。

class ReportGenerator:def preprocess_data(self, data: list[Report]):# Common preprocessing stepspassdef generate_sales_report(self, sales_data: list[Report]):self.preprocess_data(sales_data)# Generate sales reportpassdef generate_inventory_report(self, inventory_data: list[Report]):self.preprocess_data(inventory_data)# Generate inventory reportpass

3. The “long method” smell (方法太长)

def handle_customer_request(request: CustomerRequest):# Validate request# Log request details# Check inventory# Calculate pricing# Apply discounts# Finalize responsepass

“长方法”包含太多的代码行,并且通常难以阅读、理解和测试。

通过将此方法分解为更小、更集中的函数,可以提高可读性和可重用性。通过将方法分离成更小、更集中的函数,我们可以提高可读性和可重用性,并简化单元测试。我们应该致力于使每种方法都负责一项单一的任务。

def handle_customer_request(request: CustomerRequest):validate_request(request)log_request(request)check_inventory(request)pricing = calculate_pricing(request)apply_discounts(pricing)return finalize_response(pricing)def validate_request(request: Request): pass
def log_request(request: Request): pass
def check_inventory(request: Request): pass
def calculate_pricing(request: Request): pass
def apply_discounts(pricing: int): pass
def finalize_response(pricing: int): pass

4. The “magic numbers” smell (神奇数字)

def calculate_shipping_cost(distance: float) -> float:return distance * 1.25  # What does 1.25 signify?

“幻数”是那些棘手的数字文字,经常出现在编程代码中,没有明显的解释,使代码更难理解和处理。该 calculate_shipping_cost 函数在没有任何上下文的情况下使用数字 1.25,让我们猜测它的目的和含义。
相反,我们可以引入一个名为 PER_MILE_SHIPPING_RATE 的常量,它清楚地表明 1.25 表示每英里的运输成本。这个简单的更改使我们的代码更易于理解,也简化了将来对此值的更改。

PER_MILE_SHIPPING_RATE = 1.25def calculate_shipping_cost(distance: float) -> float:return distance * PER_MILE_SHIPPING_RATE

5. The “nested conditionals” smell(嵌套过深)

def approve_loan(application: LoanApplication) -> bool:if application.credit_score > 600:if application.income > 30000:if application.debt_to_income_ratio < 0.4:return Trueelse:return Falseelse:return Falseelse:return False

嵌套的条件语句可能会使理解函数的流变得困难。该 approve_loan 方法被一系列难以理解的嵌套 if 语句包围。

通过重构我们的代码,以便按顺序检查每个条件,我们可以创建一个更扁平、更易于阅读和理解的结构。如果将复杂的逻辑与条件混合在一起,则可能值得将逻辑抽象为单独的函数,以使条件更易于阅读。如果您有一系列需要满足的条件,请考虑使用 any 和 all 内置函数来使条件更具可读性。

def approve_loan(application: LoanApplication) -> bool:if application.credit_score <= 600:return Falseif application.income <= 30000:return Falseif application.debt_to_income_ratio >= 0.4:return Falsereturn True

或者使用 any/all 内置函数:

def approve_loan(application: LoanApplication) -> bool:return all([application.credit_score > 600,application.income > 30000,application.debt_to_income_ratio < 0.4])

这篇关于修复糟糕的代码气味的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/897700

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所