如果写劣质代码是犯罪,那我该判无期

如果写劣质代码是犯罪,那我该判无期

导读

程序员怨恨遇到质量低质的代码,但在高压环境下,咱们常为了最快处理当下需求而疏忽代码标准,在无意识中堆积很多债款。咱们还观察到许多开发者被逼加班的元凶巨恶就是写低效代码、不注重代码优化。编程路上,欲速则不达。 接下来,我将为各位列举9种我个人工作中高频遇到的不整齐代码行为,并提出针对性优化建议。继续阅览~

目录

1 代码风格和可读性

2 注释

3 过错处理和反常处理

4 代码复用和模块化

5 硬编码

6 测验和调试

7 功能优化

8 代码安全性

9 版别操控和协作

10 总结

01、代码风格和可读性

  • 过错习气
不一致的命名规矩:运用多种命名规矩,如 camelCase、snake_case 和 PascalCase 等。过长的函数和办法:编写过长的函数和办法,导致代码难以阅览和了解。 过长的行:编写超越50字符的代码行,导致代码难以阅览。

1.1 变量命名不标准

在编程中,变量命名是非常重要的,杰出的变量命名能够进步代码的可读性和可保护性。不标准的命名会添加了解难度,以下是一个不标准命名的比如:

int a, b, c; // 不具有描述性的变量名
float f; // 不清楚变量表明的含义

这样的变量命名不只会下降代码的可读性,还或许会导致变量混淆,添加代码保护的难度。正确的做法应该运用有含义的称号来命名变量。例如:

int num1, num2, result; // 具有描述性的变量名
float price; // 明晰明了的变量名

1.2 长函数和杂乱逻辑

长函数和杂乱逻辑是另一个常见的过错和坏习气。长函数难以了解和保护,而杂乱逻辑或许导致过错和难以调试。以下是一个长函数和杂乱逻辑的事例:

def count_grade(score):
    if score >= 90:
        grade = 'A'
    elif score >= 80:
        grade = 'B'
    elif score >= 70:
        grade = 'C'
    elif score >= 60:
        grade = 'D'
    else:
        grade = 'F'
    if grade == 'A' or grade == 'B':
        result = 'Pass'
    else:
        result = 'Fail'
    return result

在这个比如中,函数 count_grade 包含了较长的逻辑和多个嵌套的条件句子,使得代码难以了解和保护。正确的做法是将逻辑拆分为多个小函数,每个函数只担任一个简单的任务,例如:

def count_grade(score):
    grade = get_grade(score)
    result = pass_or_fail(grade)
    return result
def get_grade(score):
    if score >= 90:
        return 'A'
    elif score >= 80:
        return 'B'
    elif score >= 70:
        return 'C'
    elif score >= 60:
        return 'D'
    else:
        return 'F'
def pass_or_fail(grade):
    if grade == 'A' or grade == 'B':
        return 'Pass'
    else:
        return 'Fail'

经过拆分函数,咱们使得代码愈加可读和可保护。

1.3 过长的行

代码行过长,会导致代码难以阅览和了解,添加了保护和调试的难度。例如:

def f(x):
    if x>0:return 'positive' elif x<0:return 'negative'else:return 'zero'

这段代码的问题在于,它没有正确地运用空格和换行,使得代码看起来紊乱,难以阅览。正确的办法是,咱们应该遵循一定的代码标准和风格,使得代码明晰、易读。下面是按照 PEP 8标准改写的代码:

def check_number(x):
    if x > 0:
        return 'positive'
    elif x < 0:
        return 'negative'
    else:
        return 'zero'

这段代码运用了正确的空格和换行,使得代码明晰、易读。

02、注释

  • 过错习气
短少注释:没有为代码编写注释,导致其他人难以了解代码的功用和逻辑。 过时的注释:未及时更新注释,使注释与实际代码不一致。 过错注释:注释上并不标准,常常运用一些不合理的注释。
  • 过错的注释

注释是非常重要的,杰出的注释能够进步代码的可读性和可保护性。以下是一个不标准的比如:

int num1, num2; // 界说两个变量

上述代码中,注释并没有供给有用的信息,反而添加了代码的杂乱度。

03、过错处理和反常处理

  • 过错的习气
疏忽过错:未对或许呈现的过错进行处理。 过度运用反常处理:滥用 try…except 结构,导致代码逻辑紊乱。 捕获过于广泛的反常:捕获过于广泛的反常,如 except Exception,导致难以定位问题。

3.1 疏忽过错

咱们往往会遇到各种过错和反常。假如咱们忽视了过错处理,那么当过错产生时,程序或许会溃散,或许呈现不行预知的行为。例如:

def divide(x, y):
    return x / y

这段代码的问题在于,当 y 为0时,它会抛出 ZeroDivisionError 反常,可是这段代码没有处理这个反常。下面是改进的代码:

def divide(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        return 'Cannot divide by zero!'

3.2 过度运用反常处理

咱们或许会运用反常处理来代替条件判别,这是不适宜的。反常处理应该用于处理反常状况,而不是正常的操控流程。例如:

def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        result = float('inf')
    return result

在这个示例中,咱们运用反常处理来处理除以零的状况。正确做法:

def divide(a, b):
    if b == 0:
        result = float('inf')
    else:
        result = a / b
    return result

在这个示例中,咱们运用条件判别来处理除以零的状况,而不是运用反常处理。

3.3 捕获过于广泛的反常

捕获过于广泛的反常或许导致程序溃散或隐藏潜在的问题。以下是一个事例:

try {
    // 履行一些或许抛出反常的代码
} catch (Exception e) {
    // 捕获一切反常,并疏忽过错}

在这个比如中,反常被捕获后,没有进行任何处理或记录,导致程序无法正确处理反常状况。正确的做法是根据具体状况,挑选适宜的反常处理方式,例如:

try {
    // 履行一些或许抛出反常的代码
} catch (FileNotFoundException e) {
    // 处理文件未找到反常
    logger.error("File not found", e);
} catch (IOException e) {
    // 处理IO反常
    logger.error("IO error", e);
} catch (Exception e) {
    // 处理其他反常
    logger.error("Unexpected error", e);}

经过合理的反常处理,咱们能够更好地处理反常状况,添加程序的稳定性和可靠性

04、过错处理和反常处理

  • 过错的习气
缺少复用性:代码冗余,保护困难,添加 bug 呈现的或许性。 缺少模块化:代码耦合度高,难以重构和测验。

4.1 缺少复用性

代码重复是一种非常常见的过错。当咱们需求实现某个功用时,或许会复制粘贴之前的代码来实现,这样或许会导致代码重复,添加代码保护的难度。例如:

   def calculate_area_of_rectangle(length, width):
       return length * width
   def calculate_volume_of_cuboid(length, width, height):
       return length * width * height
   def calculate_area_of_triangle(base, height):
       return 0.5 * base * height
   def calculate_volume_of_cone(radius, height):
       return (1/3) * 3.14 * radius * radius * height

上述代码中,计算逻辑存在重复,这样的代码重复会影响代码的可保护性。为了防止代码重复,咱们能够将相同的代码复用,封装成一个函数或许办法。例如:

   def calculate_area_of_rectangle(length, width):
       return length * width
   def calculate_volume(length, width, height):
       return calculate_area_of_rectangle(length, width) * height
   def calculate_area_of_triangle(base, height):
       return 0.5 * base * height
   def calculate_volume_of_cone(radius, height):
       return (1/3) * 3.14 * radius * radius * height

这样,咱们就能够防止代码重复,进步代码的可保护性。

4.2 缺少模块化

缺少模块化是一种常见的过错,这样简单形成冗余,下降代码的可保护性,例如:

   class User:
       def __init__(self, name):
           self.name = name
       def save(self):
           # 保存用户到数据库的逻辑
       def send_email(self, content):
           # 发送邮件的逻辑
   class Order:
       def __init__(self, user, product):
           self.user = user
           self.product = product
       def save(self):
           # 保存订单到数据库的逻辑
       def send_email(self, content):
           # 发送邮件的逻辑
   ```

此例中,User 和 Order 类都包含了保存和发送邮件的逻辑,导致代码重复,耦合度高。咱们能够经过将发送邮件的逻辑提取为一个独立的类,例如:

   class User:
       def __init__(self, name):
           self.name = name
       def save(self):
           # 保存用户到数据库的逻辑
   class Order:
       def __init__(self, user, product):
           self.user = user
           self.product = product
       def save(self):
           # 保存订单到数据库的逻辑
   class EmailSender:
       def send_email(self, content):
           # 发送邮件的逻辑

经过把发送邮件单独提取出来,实现了模块化。现在 User 和 Order 类只担任自己的中心功用,而发送邮件的逻辑由 EmailSender 类担任。这样一来,代码愈加明晰,耦合度下降,易于重构和测验。

05、硬编码

  • 过错的习气
常量:设置固定常量,导致保护困难。 全局变量:过度运用全局变量,导致程序的状况难以盯梢。

5.1 常量

在编程中,咱们常常需求运用一些常量,如数字、字符串等。然而,直接在代码中硬编码这些常量是一个欠好的习气,由于它们或许会在未来产生变化,导致保护困难。例如:

def calculate_score(score):
    if (score > 60) {
    // do something}

这里的60就是一个硬编码的常量,导致后续保护困难,正确的做法应该运用常量或许枚举来表明。例如:

PASS_SCORE = 60;
def calculate_score(score):
    if (score > PASS_SCORE) {
        // do something    }

这样,咱们就能够防止硬编码,进步代码的可保护性。

5.2 全局变量

过度运用全局变量在全局范围内都能够拜访和修正。因而,过度运用全局变量或许会导致程序的状况难以盯梢,添加了程序出错的或许性。例如:

counter = 0
def increment():
    global counter
    counter += 1

这段代码的问题在于,它运用了全局变量 counter,使得程序的状况难以盯梢。咱们应该尽量减少全局变量的运用,而是运用函数参数和返回值来传递数据。例如:

def increment(counter):
    return counter + 1

这段代码没有运用全局变量,而是运用函数参数和返回值来传递数据,使得程序的状况更易于盯梢。

06、测验和调试

  • 过错的习气
单元测验:不进行单元测验会导致无法及时发现和修正代码中的过错,添加代码的不稳定性和可保护性。 鸿沟测验:不进行鸿沟测验或许导致代码在鸿沟状况下呈现过错或反常。 代码的可测验性:有些状况依靠于当时条件,使测验变得很难。

6.1 单元测验

单元测验是验证代码中最小可测验单元的办法,下面是不添加单元测验的事例:

def add_number(a, b):
    return a + b

在这个示例中,咱们没有进行单元测验来验证函数 add_number 的正确性。正确示例:

import unittest
def add_number(a, b):
    return a + b
class TestAdd(unittest.TestCase):
    def add_number(self):
        self.assertEqual(add(2, 3), 5)
if __name__ == '__main__':    unittest.main()

在这个示例中,咱们运用了 unittest 模块进行单元测验,保证函数 add 的正确性。

6.2 鸿沟测验

鸿沟测验是针对输入的鸿沟条件进行测验,以验证代码在鸿沟状况下的行为下面是过错示例:

def is_even(n):
    return n % 2 == 0

在这个示例中,咱们没有进行鸿沟测验来验证函数 is_even 在鸿沟状况下的行为。正确示例:

import unittest
def is_even(n):
    return n % 2 == 0
class TestIsEven(unittest.TestCase):
    def test_even(self):
        self.assertTrue(is_even(2))
        self.assertFalse(is_even(3))
if __name__ == '__main__':    unittest.main()

在这个示例中,咱们运用了 unittest 模块进行鸿沟测验,验证函数 is_even 在鸿沟状况下的行为。

6.3 可测验性

代码的可测验性咱们需求编写测验来验证代码的正确性。假如咱们忽视了代码的可测验性,那么编写测验将会变得困难,乃至无法编写测验。例如:

def get_current_time():
    return datetime.datetime.now()

这段代码的问题在于,它依靠于当时的时刻,这使得咱们无法编写确定性的测验。咱们应该尽量减少代码的依靠,使得代码更易于测验。例如:

def get_time(now):
    return now

这段代码不再依靠于当时的时刻,而是经过参数传入时刻,这使得咱们能够编写确定性的测验。

07、功能优化

  • 过错的习气
过度优化:过度优化或许会导致代码难以了解和保护,乃至或许会引进新的过错。 适宜的数据结构:挑选适宜的数据结构能够进步代码的功能。

7.1 过度优化

咱们往往会试图优化代码,使其运行得更快。然而,过度优化或许会导致代码难以了解和保护,乃至或许会引进新的过错。例如:

def sum(numbers):
    return functools.reduce(operator.add, numbers)

这段代码的问题在于,它运用了 functools.reduce 和 operator.add 来计算列表的和,尽管这样做能够进步一点点功能,可是这使得代码难以了解。咱们应该在保持代码明晰和易读的前提下,进行适度的优化。例如:

def sum(numbers):
    return sum(numbers)

这段代码运用了内置的 sum 函数来计算列表的和,尽管它或许比上面的代码慢一点,可是它更明晰、易读。

7.2 没有运用适宜的数据结构

挑选适宜的数据结构能够进步代码的功能。运用不适宜的数据结构或许导致代码履行缓慢或占用过多的内存。例如:

def find_duplicate(numbers):
    duplicates = []
    for i in range(len(numbers)):
        if numbers[i] in numbers[i+1:]:
            duplicates.append(numbers[i])
    return duplicates

在这个示例中,咱们运用了列表来查找重复元素,但这种办法的时刻杂乱度较高。咱们能够运用调集来查找元素。例如:

def find_duplicate(numbers):
    duplicates = set()
    seen = set()
    for num in numbers:
        if num in seen:
            duplicates.add(num)
        else:
            seen.add(num)
    return list(duplicates)

咱们运用了调集来查找重复元素,这种办法的时刻杂乱度较低。

08、代码安全性

  • 过错的习气
输入验证:不正确的输入验证或许导致安全漏洞,如 SQL 注入、跨站脚本进犯等。 暗码存储:不正确的暗码存储或许导致用户暗码走漏。 权限操控:不正确的权限操控或许导致未经授权的用户拜访灵敏信息或履行特权操作。

8.1 输入验证

没有对用户输入进行充沛验证和过滤或许导致恶意用户履行恶意代码或获取灵敏信息。例如:

import sqlite3
def get_user(username):
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    query = f"SELECT * FROM users WHERE username = '{username}'"
    cursor.execute(query)
    user = cursor.fetchone()
    conn.close()
    return user

在这个示例中,咱们没有对用户输入的 username 参数进行验证和过滤,或许导致 SQL 注入进犯。正确示例:

import sqlite3
def get_user(username):
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    query = "SELECT * FROM users WHERE username = ?"
    cursor.execute(query, (username,))
    user = cursor.fetchone()
    conn.close()
    return user

在这个示例中,咱们运用参数化查询来过滤用户输入,防止了 SQL 注入进犯。

8.2 不正确的暗码存储

将明文暗码存储在数据库或文件中,或运用不安全的哈希算法存储暗码都是不安全的做法。过错示例:

import hashlib
def store_password(password):
    hashed_password = hashlib.md5(password.encode()).hexdigest()
    # 存储 hashed_password 到数据库或文件中

在这个示例中,咱们运用了不安全的哈希算法 MD5 来存储暗码。正确示例:

import hashlib
import bcrypt
def store_password(password):
    hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
    # 存储 hashed_password 到数据库或文件中

在这个示例中,咱们运用了更安全的哈希算法 bcrypt 来存储暗码。

8.3 不正确的权限操控

没有正确验证用户的身份和权限或许导致安全漏洞。过错示例:

def delete_user(user_id):
    if current_user.is_admin:
        # 履行删去用户的操作
    else:
        raise PermissionError("You don't have permission to delete users.")

在这个示例中,咱们只查看了当时用户是否为办理员,但没有进行足够的身份验证和权限验证。正确示例:

def delete_user(user_id):
    if current_user.is_authenticated and current_user.is_admin:
        # 履行删去用户的操作
    else:
        raise PermissionError("You don't have permission to delete users.")

在这个示例中,咱们不只查看了当时用户是否为办理员,还查看了当时用户是否已经经过身份验证。

09、版别操控和协作

  • 过错的习气
版别提交信息:不合理的版别提交信息会形成开发人员难以了解和追寻代码的变化。 疏忽版别操控和备份:没有备份代码和版别操控的文件或许导致丢掉代码、难以追溯过错来源和无法回滚等问题。

9.1 版别提交信息

不合理的版别提交信息或许导致代码丢掉、开发人员难以了解等问题。过错示例:

git commit -m "Fixed a bug"

在这个比如中,提交信息没有供给足够的上下文和详细信息,导致其他开发人员难以了解和追寻代码的变化。正确的做法是供给有含义的提交信息,例如:

$ git commit -m "Fixed a bug in calculate function, which caused grade calculation for scores below 60"

经过供给有含义的提交信息,咱们能够更好地追寻代码的变化,帮助其他开发人员了解和保护代码。

9.2 疏忽版别操控和备份

疏忽运用版别操控东西进行代码办理和备份是一个常见的过错。过错示例:

$ mv important_code.py important_code_backup.py
$ rm important_code.py

在这个示例中,开发者没有运用版别操控东西,仅仅简单地对文件进行重命名和删去,没有进行恰当的备份和记录。正确示例:

$ git clone project.git
$ cp important_code.py important_code_backup.py
$ git add .
$ git commit -m "Created backup of important code"
$ git push origin master
$ rm important_code.py

在这个示例中,开发者运用了版别操控东西进行代码办理,并在删去之前创建了备份,保证了代码的安全性和可追溯性。

10、总结

好的代码应该如同一首好文,让人爱不释手。高雅的代码,不仅仅功用完善,更要做好每一个细节。

最终,引用韩磊教师在《代码整齐之道》写到的一句话送给大家:

细节之中自有天地,整齐成果卓越代码。

以上是本文全部内容,欢迎分享。

-End-

原创作者|孔垂航

技能责编|刘银松

如果写劣质代码是犯罪,那我该判无期

写代码时犯过什么搞笑的初级过错?你又有什么防止过错的好办法?欢迎在腾讯云开发者大众号评论区分享评论。咱们将选取1则最有含义的分享,送出腾讯云开发者-手腕垫1个(见下图)。7月24日正午12点开奖。

如果写劣质代码是犯罪,那我该判无期

如果写劣质代码是犯罪,那我该判无期

如果写劣质代码是犯罪,那我该判无期

如果写劣质代码是犯罪,那我该判无期

如果写劣质代码是犯罪,那我该判无期