您的代码很糟糕,因为可能有很多情况可以对其进行编辑或改进。
大多数这些气味只是暗示可能有问题。因此,它们本身并不需要被修复……(不过,你应该研究一下。)
您可以在这里找到所有以前的代码味道(第一部分 - XLV)。
让我们继续...
又一艘坠毁的航天器。另一个软件问题
TL;DR:设计并测试软件。比硬件便宜
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()
这是设计的味道
创建软件组件并模拟真实和非真实的条件
代码味道是我的观点。
分析引擎没有任何意图来创造任何东西。它可以做任何我们知道如何命令它执行的事情……但它很可能对科学本身产生间接和相互的影响。
艾达·洛夫莱斯
把牛仔留给好莱坞电影吧。
TL;DR:作为团队程序员编写代码
编写专业代码。
使用声明性的非神秘名称。
牛仔程序员不遵循最佳实践。
他们不遵循团队的建议。
牛仔编码通常被认为是一种不专业且有风险的软件开发方法,因为它可能导致代码难以维护且容易出错。
牛仔程序员都是好人;然而,他们不能在一个团队中工作。
# 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()
您可以设置环境规则来防止这些编码实践并加强团队建设。
软件开发是团队合作的。
https://www.linkedin.com/pulse/software-development-cowboy-coding-hakan-atbaş/
泰勒·布兰登 (Taylor Brandon)在Unsplash上拍摄的照片
计算机的危险并不在于它们最终会变得像人类一样聪明,而是我们同时同意与它们相向而行。
伯纳德·阿维沙伊
超过一堂课就乱了。
TL;DR:遵循关注点分离原则和文件组织
每个文件声明一个类
使用名称范围
在使用文件系统声明类的语言中,每个文件一个类通常被认为是最佳实践。
这种方法有助于提高代码组织和可维护性,并减少潜在问题。
您可以将命名空间组织到项目结构中的单独目录中。
这样,您可以维护逻辑且高效的代码库,同时避免在单个文件中声明多个类的问题。
<? 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"; } }
许多标准都强制执行此规则
让您的代码井井有条,并遵循已知的标准。
照片由Marjan Blan在Unsplash上拍摄
没有需求或设计,编程就是向空文本文件添加错误的艺术。
路易斯·施瑞格利
您的代码过于复杂。
TL;DR:避免意外的复杂性和官僚主义
“繁文缛节”代码味道可能与不必要的复杂性、官僚主义或过度配置有关,这些配置使代码库更难以理解或维护。
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.
有些工具可能会猜测您正在用不必要的责任来膨胀您的对象。
繁文缛节的代码味道很明显,因为开发人员需要浏览复杂的配置来确定哪些功能处于活动状态。
这不仅增加了不必要的复杂性,而且还增加了可能影响系统完整性的错误配置的可能性。
代码味道是我的观点。
软件的一个谬论:如果它有效,而我们不改变任何东西,它就会继续有效。
杰西卡·克尔
你的代码既死又活。
TL;DR:仔细查看竞争条件
避免竞争条件
避免全局变量
使用正确的同步
薛定谔代码是可以同时处于两种不同状态的代码,但代码的状态要等到执行时才能确定。
当代码包含竞争条件时,或者当代码依赖于可由其他线程或进程更改的全局变量的状态时,可能会发生这种情况。
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.
对并发代码进行代码审查
为了避免薛定谔代码,请避免竞争条件并避免依赖于可由其他线程或进程更改的全局变量的状态。
如果您需要在代码中使用全局变量,请确保其正确同步。
照片由Unsplash上的Yerlin Matu拍摄
您希望任何程序员做的最后一件事就是弄乱内部状态
艾伦·凯
下周,还会有 5 种气味。