workspace
成熟带来独特的观点。
当我开始编写代码时,有人告诉我:
但随着时间的推移,我意识到这些都是谎言。对于年轻的开发人员来说,应对软件开发的复杂性是具有挑战性的。这就是为什么我们开发人员痴迷于真理的原因。
在这里,我将分享其中的四个真理。
不要将共享代码提取到库中大多数为程序员编写的文章告诉我们不要重复找轮子。我们应该尽可能多地使用现有的代码。
这就是为什么我们开发人员痴迷于在可能的情况下将共享代码提取到库中的原因。
但是这种提取共享代码的习惯也可能是灾难性的。我观察到提取共享代码会导致依赖性增加。
你经常会发现自己花费时间维护几乎不使用的库。无用的库会引入额外的开销。你将有额外的代码要管理。
举例:
假设我们创建了一个用于计算奇数和偶数的库。
# odd_even_library.py
def is_odd(num):
return num % 2 != 0
def is_even(num):
return num % 2 == 0
# 主要代码
from odd_even_library import is_odd, is_even
number = 7
if is_odd(number):
print(f"{number} 是奇数。")
else:
print(f"{number} 是偶数。")
上面的代码使用了一个库。
现在看下一个例子,我们不使用库。
def is_odd(num):
return num % 2 != 0
def is_even(num):
return num % 2 == 0
# 主要代码
number = 7
if is_odd(number):
print(f"{number} 是奇数。")
else:
print(f"{number} 是偶数。")
在第一个案例中,我们创建了一个名为 odd_even_library.py 的库,其中包含奇数和偶数计算的函数。如果我们想在主代码中使用该库,我们必须导入它。这引入了对 odd_even_library 模块的依赖性。如果库有其他依赖性,那么它也将成为主代码的一部分。
我用一个简单的例子向你展示这一点。但如果你愿意,你可以采用一个复杂的例子。当库有它们自己的依赖关系时,将导致复杂的依赖关系树。
我们该怎么办?
如果以**odd_even_library.py**为例。你会发现我们很早就创建了这个库。我们不知道将来会如何使用它。如果你创建一个库,而在那时你不知道将来如何使用它。那就不要创建它。它只会在将来给你带来不必要的麻烦。
使用领域语言我记得我刚开始写代码的时候。我总是听从指导。指导总是使用领域的语言。我以为指导之所以使用领域的语言是为了显得酷。那时我并不明白它的重要性。当我开始独立构建项目时,我没有使用领域的语言。
如果我正在构建图书管理系统,我不会使用函数名add_book,find_book_by_title 和 list_all_books 。而是使用相当通用的名称。我能够使用通用名称构建许多项目。由于只有我一个人编码,我没有任何问题。
这对我的思考产生了什么影响?
我开始相信使用特定领域语言是一种浪费时间,因为我能够在没有使用它的情况下创建许多个人项目。
当我阅读其他人为任何开源软件编写的代码时,他们使用了特定领域的语言。我认为每个人都在浪费时间。我认为他们可以只使用通用名称,一切都还会好。
什么时候一切对我产生了改变?
现在当我写这篇文章时,我记不得确切的代码。但我肯定记得那个情境。我记得我构建了一个博客平台,在那里我刻意没有使用领域语言。我使用了一个通用的名称。
让我给你一个这样的代码例子。
def calculate(a, b):
x = a b
y = x * 2
z = y / 3
return z
result = calculate(5, 7)
print("Result:", result)
上面有一个简单的calculate 函数。它接受两个参数 a 和 b。该函数包含三个变量 x、y 和 z。这些变量名并没有给我们任何关于它们存在的目的的上下文。
仅仅为了正确理解代码,你必须分析整个代码。在修复任何错误时,你将会在进行更改时感到困扰。你必须记住为什么代码库中存在任何变量。如果你作为一个团队工作,你的队友在理解代码时会面临挑战。
在我的情况下,当我回到我的项目并尝试对其进行更改时,我感到困扰。为了进行单一更改,我必须追踪各种变量。我用笔和纸只是为了追踪每个变量的存在目的。在那一刻,我批评了整个方法。我学到了一个宝贵的教训。
如果先前的代码是这样的:
def calculate_sum_and_average(first_number, second_number):
sum_of_numbers = first_number second_number
double_sum = sum_of_numbers * 2
average = double_sum / 3
return average
result = calculate_sum_and_average(5, 7)
print("Average:", result)
对于必要的更改来说会更容易。在上面的代码中,我们对变量和函数使用了有意义的名称。
写一个具有一层抽象的函数当我阅读其他程序员编写的代码时,我反复看到这种行为。一些程序员不按照一层抽象写代码。
使用一个例子来理解抽象
在深入了解程序员如何犯这个错误之前。让我们首先通过一个例子了解抽象是什么意思。
以电视遥控器为例。
当我们使用遥控器时,我们不需要知道电视内部发生的所有复杂事情。你不需要知道电视扬声器的音量是如何升降的。遥控器上的按钮如何改变图像显示?要访问电视的复杂性而不完全理解其内部工作原理,使用遥控器。
浏览器的例子
以任何网络浏览器为例。
Google Chrome。
你输入youtube.com,网站会自动打开。你不需要知道HTTP是如何工作的,服务器是什么。它只是运行。
程序员会常犯错误?
#计算矩形面积的函数
def calculate_rectangle_area(length, width):
arduinoCopy code
return length * width
#计算矩形面积的函数
def calculate_rectangle_area(length, width):
return length * width
# Function to ask the user for dimensions
def get_and_calculate_rectangle_area():
length = float(input("输入矩形的长度: "))
width = float(input("输入矩形的宽度: "))
area = calculate_rectangle_area(length, width)
print(f"矩形的面积是: {area}")
def main():
print("使用矩形面积计算器")
get_and_calculate_rectangle_area()
在上面的例子中,get_and_calculate_rectangle_area 函数负责用户输入和面积计算两者的功能。这导致了复杂性的增加。
如果你能够将责任分为两个单独的函数,代码会变得更简单。
更好的做法应该是这样的
# **计算面积的函数**
def calculate_rectangle_area(length, width):
return length * width
# Main function
def main():
print("使用矩形面积计算器")
length = float(input("输入矩形的长度: "))
width = float(input("输入矩形的宽度: "))
area = calculate_rectangle_area(length, width)
print(f"矩形的面积是: {area}")
在上面的代码中,calculate_rectangle_area 函数是唯一负责计算面积的函数。该函数没有额外的抽象层次。主函数处理整个流程。它显示消息并调用 calculate_rectangle_area 来计算面积。通过这样做,我们将抽象减少到了一层。
编程没有固定的答案在第一点中,我已经提到不应该将共享代码单独提取成库。而在第三点中,我建议编写具有一层抽象的函数。
第一个原则是避免为共享代码创建独立的库和外部依赖,而是将代码保持在项目内。第三个原则则侧重于创建具有清晰单一职责的函数。这鼓励将复杂的操作分解为更小、更专注的单元。或许你会认为存在一些矛盾。但仔细思考后,实际上并不存在真正的矛盾。
我想表达什么?
我并不是说永远不应该将共享代码放入库中。而是如果尝试将代码放入独立的库中,请确保该代码不仅仅适用于当前项目,还适用于其他场景。如果提取的代码有助于组织代码并提高可维护性,那么你应该继续制作库。这符合编写仅具有一层抽象的函数的原则。
在拉取共享代码并将其放入一个库中时,请权衡利弊。
如果项目所需的代码行数较少,就不要通过添加不必要的文件使项目变得庞大。事情会不断发展变化编程始终处于不断变化的状态。不断涌现出新的框架、原则和工具。在一个情境中被认为是最佳实践的方法,在另一个情境中可能是最差的。
因此,你应该努力学习所有最佳实践,但根据用户的需求做出决策。解决相同问题可能有多种方法;你应该根据具体情境选择最佳方法。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved