paint-brush
如何找到代码中的臭部分 [第 XLVI 部分]经过@mcsee
635 讀數
635 讀數

如何找到代码中的臭部分 [第 XLVI 部分]

经过 Maximiliano Contieri10m2023/11/27
Read on Terminal Reader

太長; 讀書

牛仔程序员不遵循最佳实践。 他们不遵循团队的建议。 牛仔编码通常被认为是一种不专业且有风险的软件开发方法,因为它可能导致代码难以维护且容易出错。
featured image - 如何找到代码中的臭部分 [第 XLVI 部分]
Maximiliano Contieri HackerNoon profile picture

您的代码很糟糕,因为可能有很多情况可以对其进行编辑或改进。


大多数这些气味只是暗示可能有问题。因此,它们本身并不需要被修复……(不过,你应该研究一下。)

以前的代码味道

您可以在这里找到所有以前的代码味道(第一部分 - XLV)。


让我们继续...


代码气味 226 - 混合优先级

又一艘坠毁的航天器。另一个软件问题


TL;DR:设计并测试软件。比硬件便宜

问题

解决方案

  1. 创建准确的模拟
  2. 制作容错软件

语境

Luna-25于 2023 年 8 月 19 日在月球表面坠毁。


距离印度月船三号软着陆月球南极还有 4 天。


取证分析显示,这些指令共享一条总线,并且优先级不正确。


航天器的软件故障由来已久

示例代码

错误的

class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # No sorting for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()

正确的

class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # Sort tasks by priority (high to low) self.tasks.sort(key=lambda x: x[1], reverse=True) for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()

检测

  • [x]手册

这是设计的味道

标签

  • 可靠性

结论

创建软件组件并模拟真实和非真实的条件

关系

代码气味 198 - 隐藏的假设

更多信息

免责声明

代码味道是我的观点


分析引擎没有任何意图来创造任何东西。它可以做任何我们知道如何命令它执行的事情……但它很可能对科学本身产生间接和相互的影响。


艾达·洛夫莱斯

软件工程名言


代码气味 227 - 牛仔编码

把牛仔留给好莱坞电影吧。


TL;DR:作为团队程序员编写代码

问题

  • 可读性
  • 代码不可靠
  • 人员管理问题
  • 缺乏协调

解决方案

  1. 编写专业代码。


  2. 使用声明性的非神秘名称。

语境

牛仔程序员不遵循最佳实践。


他们不遵循团队的建议。


牛仔编码通常被认为是一种不专业且有风险的软件开发方法,因为它可能导致代码难以维护且容易出错。


牛仔程序员都是好人;然而,他们不能在一个团队中工作

示例代码

错误的

# Very simple example # Compute the sum of two numbers without any structure or best practices. num1 = input("Enter the first number: ") num2 = input("Enter the second number: ") # WARNNING!!!! Don't remove the line below !!!!! # (Unpleasant comment) res = num1 + num2 # (No data type checking or error handling) print("The sum is: " + result) # (No validation or formatting) # (No good names, no functions, no error handling, no testing, # no version control, and no structure.)

正确的

def add_numbers(): try: firstAddend = float(input("Enter the first number: ")) secondAddend = float(input("Enter the second number: ")) total = firstAddend + secondAddend return total except ValueError: print("Invalid input. Please enter valid numbers.") return None def main(): total = add_numbers() if total is not None: print("The sum is: {:.2f}".format(sum)) if __name__ == "__main__": main()

检测

  • [x]手册


您可以设置环境规则来防止这些编码实践并加强团队建设。

例外情况

  • 非常小的个人项目

标签

  • 声明式

结论

软件开发是团队合作的。

关系

代码味道 06 - 太聪明的程序员

代码气味 02 - 常量和幻数

代码气味 105 - 喜剧演员的方法

更多信息

https://www.linkedin.com/pulse/software-development-cowboy-coding-hakan-atbaş/

制作人员

泰勒·布兰登 (Taylor Brandon)Unsplash上拍摄的照片


计算机的危险并不在于它们最终会变得像人类一样聪明,而是我们同时同意与它们相向而行。

伯纳德·阿维沙伊


代码气味 228 - 每个文件有多个类

超过一堂课就乱了。


TL;DR:遵循关注点分离原则和文件组织

问题

  • 代码组织
  • 耦合
  • 自动加载问题
  • 调试
  • 版本控制和合并冲突

解决方案

  1. 每个文件声明一个类


  2. 使用名称范围

语境

在使用文件系统声明类的语言中,每个文件一个类通常被认为是最佳实践。


这种方法有助于提高代码组织和可维护性,并减少潜在问题。


您可以将命名空间组织到项目结构中的单独目录中。


这样,您可以维护逻辑且高效的代码库,同时避免在单个文件中声明多个类的问题。

示例代码

错误的

<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } } class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }

正确的

<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } }
 <? namespace MyNamespace; class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }

检测

  • [x]自动

许多标准都强制执行此规则

标签

  • 耦合

结论

让您的代码井井有条,并遵循已知的标准。

关系

代码气味 48 - 没有标准的代码

更多信息

制作人员

照片由Marjan BlanUnsplash上拍摄


没有需求或设计,编程就是向空文本文件添加错误的艺术。


路易斯·施瑞格利


代码气味 229 - 繁文缛节

您的代码过于复杂。


TL;DR:避免意外的复杂性和官僚主义

问题

解决方案

  1. 使用MAPPER将职责分配给现实世界的对象。

语境

“繁文缛节”代码味道可能与不必要的复杂性、官僚主义或过度配置有关,这些配置使代码库更难以理解或维护。

示例代码

错误的

class VotingSystem: def __init__(self, config): self.config = config def validate_voter(self, voter_id): if self.config['voter_verification_enabled']: # Code to verify the voter's identity goes here def cast_vote(self, voter_id, candidate): if self.config['voting_enabled']: # Code to record the vote goes here def generate_vote_report(self): if self.config['generate_report']: # Code to generate a voting report goes here def audit_voting_system(self): if self.config['audit_enabled']: # Code to perform an audit of the voting system goes here # ... other voting-related methods ... # Usage config = { 'voter_verification_enabled': True, 'voting_enabled': False, 'generate_report': False, 'audit_enabled': True } voting_system = VotingSystem(config) # Voter validation, voting, report generation, # and auditing are handled based on the configuration.

正确的

class VoterVerification: def verify_voter(self, voter_id): # Code to verify the voter's identity goes here class VotingMachine: def cast_vote(self, voter_id, candidate): # Code to record the vote goes here class VoteReporter: def generate_report(self): # Code to generate a voting report goes here class VotingAuditor: def audit_voting_system(self): # Code to perform an audit of the voting system goes here # Usage voter_verification = VoterVerification() voting_machine = VotingMachine() vote_reporter = VoteReporter() voting_auditor = VotingAuditor() # Voter verification, vote casting, report generation, # and auditing are handled separately.

检测

  • [x]半自动

有些工具可能会猜测您正在用不必要的责任来膨胀您的对象。

标签

  • 腹胀

结论

繁文缛节的代码味道很明显,因为开发人员需要浏览复杂的配置来确定哪些功能处于活动状态。


这不仅增加了不必要的复杂性,而且还增加了可能影响系统完整性的错误配置的可能性。

关系

代码气味 54 - 锚船

免责声明

代码味道是我的观点

制作人员

照片来自Unsplash上的放大


软件的一个谬论:如果它有效,而我们不改变任何东西,它就会继续有效。

杰西卡·克尔


代码气味 230 - 薛定谔代码

你的代码既死又活。


TL;DR:仔细查看竞争条件

问题

解决方案

  1. 避免竞争条件


  2. 避免全局变量


  3. 使用正确的同步

语境

薛定谔代码是可以同时处于两种不同状态的代码,但代码的状态要等到执行时才能确定。


当代码包含竞争条件时,或者当代码依赖于可由其他线程或进程更改的全局变量的状态时,可能会发生这种情况。

示例代码

错误的

import threading cats_alive = 0 def thread_1(): cats_alive += 1 def thread_2(): cats_alive -= 1 if cats_alive > 0: feedThem() # The value of cats_alive is indeterminate, # so the code can be in either of the two states: # # 1. cats_alive > 0 and feedThem() is called. # 2. cats_alive <= 0 and feedThem() is not called.

正确的

import threading lock = threading.Lock() cats_alive = 0 def thread_1(): with lock: cats_alive += 1 def thread_2(): with lock: cats_alive -= 1 if cats_alive > 0: feedThem() # With the lock, the two threads cannot access # the `cats_alive` variable at the same time. # This means that the value of `cats_alive` is always determined, # and the program will not exhibit Schrödinger code behavior.

检测

  • [x]手册

对并发代码进行代码审查

标签

  • 并发性
  • 全局变量

结论

为了避免薛定谔代码,请避免竞争条件并避免依赖于可由其他线程或进程更改的全局变量的状态。


如果您需要在代码中使用全局变量,请确保其正确同步。

关系

代码气味 198 - 隐藏的假设

代码气味 32 - 单例

代码气味 60 - 全局类

制作人员

照片由Unsplash上的Yerlin Matu拍摄


您希望任何程序员做的最后一件事就是弄乱内部状态

艾伦·凯


下周,还会有 5 种气味。