程序员进阶工程师必备技能之代码质量与重构能力(二)

简介: 教程来源 https://vrhyh.cn/ 本文系统阐述优秀代码的五大核心特征:命名需名副其实、可读可搜;函数应短小专注、参数精简、无副作用、抽象层次统一;注释重在解释“为什么”而非“是什么”;错误处理要显式、安全、可恢复;格式风格须一致,借助Black等工具自动化保障。

二、优秀代码的核心特征

2.1 命名艺术
命名是编程中最难的事情之一(有句名言:计算机科学中只有两件难事:缓存失效和命名)。好的命名让代码自文档化。

命名原则:

名副其实:名字要准确表达意图

避免误导:不要用容易混淆的名字

有意义的区分:Product 和 ProductInfo 没有区别

读得出来:方便讨论和搜索

可搜索性:避免魔法数字和单字母变量

# ❌ 糟糕的命名
def d(x, y):
    t = 0
    for i in x:
        t += i * y
    return t

# ✅ 优秀的命名
def calculate_total_price(item_prices: List[Decimal], tax_rate: Decimal) -> Decimal:
    """
    计算含税总价
    """
    subtotal = sum(item_prices)
    tax = subtotal * tax_rate
    return subtotal + tax

# 更多命名示例
class BadNames:
    def proc(self, d1, d2):
        self.a = d1
        self.b = d2
        self.f = True

class GoodNames:
    def process_payment(self, order_amount: Decimal, user_balance: Decimal) -> PaymentResult:
        self.order_amount = order_amount
        self.user_balance = user_balance
        self.payment_successful = True

# 魔法数字 vs 命名常量
# ❌ 糟糕
if user.age > 18:
    grant_access()

# ✅ 优秀
LEGAL_AGE_THRESHOLD = 18
if user.age >= LEGAL_AGE_THRESHOLD:
    grant_access()

# 布尔变量命名
# ❌ 糟糕
is_not_valid = True
no_error = False

# ✅ 优秀
is_valid = True
has_error = False
can_edit = True
should_retry = False

2.2 函数设计
函数是代码组织的基本单元。好的函数应该短小、专注、只做一件事。

函数设计原则:

短小:函数应该只做一件事,并且把这件事做好

参数少:理想情况下0-2个参数,3个参数需要仔细考虑,超过3个应该封装成对象

无副作用:函数要么修改对象状态,要么返回计算结果,不要两者都做

单一抽象层次:函数内不要混合高层和低层抽象

# ❌ 糟糕的函数设计
def process_user_data(user_data):
    # 验证 - 高层抽象
    if not user_data.get('email'):
        raise ValueError("Email required")
    if '@' not in user_data['email']:
        raise ValueError("Invalid email")

    # 数据库操作 - 低层抽象
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users WHERE email = ?", (user_data['email'],))
    existing = cursor.fetchone()

    # 业务逻辑 - 中层抽象
    if existing:
        return "User already exists"

    # 密码哈希 - 低层抽象
    hashed = hashlib.sha256(user_data['password'].encode()).hexdigest()

    # 更多数据库操作
    cursor.execute("INSERT INTO users (email, password_hash) VALUES (?, ?)", 
                   (user_data['email'], hashed))
    conn.commit()

    # 发送邮件 - 高层抽象
    smtp = smtplib.SMTP('smtp.gmail.com', 587)
    smtp.login('me@gmail.com', 'password')
    smtp.sendmail(...)

    return "User created"


# ✅ 优秀的函数设计(单一抽象层次)
def register_user(user_data: Dict) -> RegistrationResult:
    """
    注册用户 - 高层协调函数
    只负责编排,具体细节交给其他函数
    """
    # 1. 验证输入(同一抽象层次)
    validation_result = validate_user_input(user_data)
    if not validation_result.is_valid:
        return RegistrationResult.failure(validation_result.errors)

    # 2. 检查用户是否存在(同一抽象层次)
    if user_exists(user_data['email']):
        return RegistrationResult.failure("User already exists")

    # 3. 创建用户(同一抽象层次)
    user = create_user(user_data)

    # 4. 发送欢迎邮件(同一抽象层次)
    send_welcome_email(user)

    return RegistrationResult.success(user)

def validate_user_input(user_data: Dict) -> ValidationResult:
    """验证用户输入 - 单一职责"""
    errors = []

    if not user_data.get('email'):
        errors.append("Email is required")
    elif not is_valid_email(user_data['email']):
        errors.append("Invalid email format")

    if not user_data.get('password'):
        errors.append("Password is required")
    elif len(user_data['password']) < 8:
        errors.append("Password must be at least 8 characters")

    return ValidationResult(is_valid=len(errors) == 0, errors=errors)

def user_exists(email: str) -> bool:
    """检查用户是否存在 - 单一职责"""
    # 低层抽象在辅助函数内部
    with get_db_connection() as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT 1 FROM users WHERE email = ?", (email,))
        return cursor.fetchone() is not None

def create_user(user_data: Dict) -> User:
    """创建用户 - 单一职责"""
    hashed_password = hash_password(user_data['password'])

    user = User(
        email=user_data['email'],
        password_hash=hashed_password,
        created_at=datetime.now()
    )

    with get_db_connection() as conn:
        # 保存到数据库...
        pass

    return user

def send_welcome_email(user: User):
    """发送欢迎邮件 - 单一职责"""
    # 邮件发送细节...
    pass

函数参数设计:

# ❌ 参数过多
def create_order(user_id, product_ids, quantities, prices, shipping_address, billing_address, coupon_code, gift_wrap):
    pass

# ✅ 使用数据类封装参数
@dataclass
class OrderRequest:
    user_id: str
    items: List[OrderItem]
    shipping_address: Address
    billing_address: Address
    coupon_code: Optional[str] = None
    gift_wrap: bool = False

def create_order(request: OrderRequest) -> Order:
    pass

# ✅ 使用建造者模式处理复杂参数
class OrderBuilder:
    def __init__(self, user_id: str):
        self.user_id = user_id
        self.items = []
        self.shipping_address = None
        self.coupon_code = None

    def add_item(self, product_id: str, quantity: int, price: Decimal) -> 'OrderBuilder':
        self.items.append(OrderItem(product_id, quantity, price))
        return self

    def ship_to(self, address: Address) -> 'OrderBuilder':
        self.shipping_address = address
        return self

    def with_coupon(self, coupon_code: str) -> 'OrderBuilder':
        self.coupon_code = coupon_code
        return self

    def build(self) -> Order:
        return create_order(self)

# 使用
order = OrderBuilder("user_123") \
    .add_item("product_1", 2, Decimal('19.99')) \
    .add_item("product_2", 1, Decimal('49.99')) \
    .ship_to(Address(...)) \
    .with_coupon("SAVE10") \
    .build()

2.3 注释的最佳实践
注释不是用来弥补坏代码的。好的代码应该是自解释的,注释用来解释"为什么"而不是"是什么"。

# ❌ 糟糕的注释(重复代码)
# 将价格乘以数量得到小计
subtotal = price * quantity  # 这行代码已经很清楚

# 循环遍历订单项
for item in order.items:  # 循环,很明显
    # 增加总价
    total += item.price  # 增加,也很明显

# ✅ 有用的注释(解释为什么)
# 使用Decimal而不是float来避免浮点数精度问题
price = Decimal(str(raw_price))

# 用户可能在多个设备同时登录,所以使用乐观锁
UPDATE inventory SET quantity = quantity - %s, version = version + 1 
WHERE product_id = %s AND version = %s

# 临时方案:由于支付网关的bug,需要将金额向上取整到分
# TODO(zhangsan): 支付网关修复后移除这个hack
amount = amount.quantize(Decimal('0.01'), rounding=ROUND_UP)

# 为什么选择这种算法:用户量在百万级别,布隆过滤器可以在O(1)时间内判断,
# 且内存占用只需要约10MB,如果使用Set需要数百MB
def is_duplicate_user(user_id: str) -> bool:
    return bloom_filter.contains(user_id)

# 文档注释(API文档)
def calculate_shipping_cost(
    weight: Decimal, 
    destination: Address, 
    method: ShippingMethod
) -> Decimal:
    """
    计算运费

    根据商品重量、目的地和配送方式计算运费。
    支持标准配送、快速配送和次日达三种方式。

    Args:
        weight: 商品总重量(千克)
        destination: 收货地址,用于计算距离
        method: 配送方式

    Returns:
        运费金额(元)

    Raises:
        InvalidAddressError: 当地址不支持配送时抛出
        WeightLimitExceededError: 当重量超过限制时抛出

    Example:
        >>> cost = calculate_shipping_cost(
        ...     weight=Decimal('2.5'),
        ...     destination=Address(city="Beijing"),
        ...     method=ShippingMethod.EXPRESS
        ... )
        >>> print(cost)
        23.50
    """
    pass

2.4 错误处理
优秀的代码能够优雅地处理错误,而不是崩溃或隐藏错误。

# ❌ 糟糕的错误处理
def divide(a, b):
    return a / b  # 如果b=0会崩溃

def get_user(user_id):
    return users[user_id]  # 如果key不存在会崩溃

def parse_json(data):
    return json.loads(data)  # 如果data不是有效JSON会崩溃

# ✅ 优秀的错误处理
from typing import Optional, Union
from dataclasses import dataclass

# 方式1:返回Optional/Result类型
def divide(a: float, b: float) -> Optional[float]:
    """安全除法,b为0时返回None"""
    if b == 0:
        return None
    return a / b

# 方式2:返回Result类型(类似Rust的Result)
@dataclass
class Result[T, E]:
    success: bool
    value: Optional[T] = None
    error: Optional[E] = None

    @classmethod
    def ok(cls, value: T) -> 'Result[T, E]':
        return cls(success=True, value=value)

    @classmethod
    def err(cls, error: E) -> 'Result[T, E]':
        return cls(success=False, error=error)

    def unwrap(self) -> T:
        if not self.success:
            raise ValueError(f"Called unwrap on error result: {self.error}")
        return self.value

    def unwrap_or(self, default: T) -> T:
        return self.value if self.success else default

def divide_result(a: float, b: float) -> Result[float, str]:
    if b == 0:
        return Result.err("Division by zero")
    return Result.ok(a / b)

# 使用
result = divide_result(10, 2)
if result.success:
    print(f"Result: {result.value}")
else:
    print(f"Error: {result.error}")

# 方式3:使用自定义异常
class DivisionError(Exception):
    """除法运算错误"""
    pass

def divide_raise(a: float, b: float) -> float:
    if b == 0:
        raise DivisionError("Cannot divide by zero")
    return a / b

# 调用方处理异常
try:
    result = divide_raise(10, 0)
except DivisionError as e:
    logger.error(f"Division failed: {e}")
    result = 0

# 方式4:使用装饰器统一处理
def handle_errors(default_value=None, log_error=True):
    """错误处理装饰器"""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                if log_error:
                    logging.error(f"Error in {func.__name__}: {e}")
                if default_value is not None:
                    return default_value
                raise
        return wrapper
    return decorator

@handle_errors(default_value=0, log_error=True)
def risky_operation(data):
    # 可能抛出异常的操作
    return 1 / data['value']

2.5 代码格式化与风格
一致的代码风格让团队协作更顺畅。

# 使用工具自动格式化
# - Black: 自动格式化Python代码
# - isort: 自动排序import
# - ruff: 快速linting

# .pre-commit-config.yaml 示例
repos:
  - repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
      - id: black
        language_version: python3

  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort
        args: ["--profile", "black"]

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.0.270
    hooks:
      - id: ruff
        args: [--fix, --exit-non-zero-on-fix]

# 格式化后的代码示例
# 导入分组:标准库 → 第三方库 → 本地模块
import json
import sys
from datetime import datetime
from typing import Dict, List, Optional

import pandas as pd
import requests
from fastapi import FastAPI, HTTPException

from myapp.models import Order, User
from myapp.utils import calculate_total, validate_email

def function_with_proper_formatting(
    param1: str,
    param2: int,
    param3: Optional[Dict] = None,
    param4: List[str] = None
) -> Dict[str, Any]:
    """函数文档字符串"""
    if param2 > 100:
        return {
            "status": "error",
            "message": "Parameter too large"
        }

    result = {
        "param1": param1,
        "param2": param2,
        "timestamp": datetime.now().isoformat()
    }

    return result

来源:
https://bgnno.cn/

相关文章
|
7天前
|
数据采集 机器学习/深度学习 运维
从“秒封”到“日爬十万”:谈谈5个风控机制
这篇文档讨论了Python爬虫常见问题和反爬策略。作者提出五个关键点:1. 控制请求频率;2. 轮换IP;3. 伪装请求头;4. 模拟真实访问路径;5. 使用高匿名代理。这些策略需综合运用,提高爬虫生存率。
200 5
|
7天前
|
运维 安全 机器人
增强现实技术重塑电力行业 | 瑞丰宝丽XR云平台
2026年,AR技术在电力行业规模化落地,深度赋能“源网荷储”一体化。覆盖巡检、培训、应急、建设全场景,运维效率提升45%+,事故率下降72%,缺陷识别准确率达98%。轻便AR眼镜实现“问题找人”、专家远程指导、数字孪生协同,正加速电力智能化与无人化演进。(239字)
|
1月前
|
SQL 人工智能 自然语言处理
什么是低代码 v2.0 时代?JeecgBoot低代码用 Skills 把"一句话生成系统"做成了现实
一句话先说清楚:低代码 v1.0 阶段,是用"拖拽设计"代替"代码开发";低代码 v2.0 阶段,是用 AI Skills 把"拖拽设计"也省掉, 一句话生成功能。![低代码迈入 v2.0 时代 — Skills 加持一句话搭建系统](https://oscimg.oschina.net/osc
133 5
什么是低代码 v2.0 时代?JeecgBoot低代码用 Skills 把"一句话生成系统"做成了现实
|
7天前
|
人工智能 安全 测试技术
别再让 Claude 乱改代码了!Claude Code 这 7 个权限配置让你的项目再也不翻车
还在为 Claude Code 的混乱操作头疼?本文总结 7 个核心权限配置,从上下文管理、提示技巧到环境配置全覆盖,让你的 AI 编程助手真正听话不翻车。
369 5
|
1月前
|
人工智能 IDE API
阿里云百炼Coding Plan产品简介:支持模型、收费标准及购买和使用常见问题解答
阿里云百炼Coding Plan是面向开发者和团队的AI编程订阅服务,采用固定月费模式,Pro套餐200元/月提供9万次调用额度,整合千问、Kimi、GLM、MiniMax等顶级模型,全面兼容Claude Code、OpenClaw、Cursor等主流编程工具。额度采用5小时滚动恢复、每周及每月定期重置机制,兼顾开发连续性与成本可控性。其折算成本远低于按量计费,并通过多层级额度设计和华北2地域绑定有效防范欠费风险。适合日常代码生成、智能体开发及IDE插件集成等场景,是开发者以可预期预算拥抱AI编程的高性价比选择。
阿里云百炼Coding Plan产品简介:支持模型、收费标准及购买和使用常见问题解答
|
29天前
|
人工智能 弹性计算 API
阿里云轻量应用服务器低成本部署OpenClaw方案:2核2G38元,2核4G199元,全球多地域可选
2026年阿里云轻量应用服务器低成本部署OpenClaw AI助理的方案:用户可通过每天10:00和15:00的限量抢购活动,以38元/年(2核2G/40G云盘)或9.9元/月、199元/年(2核4G/50G云盘)的价格入手服务器,预装OpenClaw镜像实现分钟级一键部署,免代码上手。部署后可通过Web UI或飞书、钉钉、QQ、企业微信等IM工具与AI智能体交互,并支持扩展Skill和自定义RPA流程。方案覆盖个人博客、AI应用开发等场景,大幅降低了AI Agent的技术与资金门槛,是低成本拥抱AI智能体的实用路径。
|
1月前
|
缓存 安全 Linux
Linux 内核 Copy Fail 漏洞对加密货币基础设施安全影响研究
2026年曝出的Linux内核漏洞Copy Fail(CVE-2026-31431),源于2017年代码缺陷,可让低权限用户稳定提权至root,具备无磁盘痕迹、跨容器逃逸、利用极简等特点,已遭野外利用。该漏洞对加密货币行业构成系统性威胁,覆盖交易所、节点、钱包、矿池等核心设施。本文基于权威报道,剖析其技术机理与风险传导,提出含内核加固、权限隔离、eBPF检测、应急响应的全生命周期防御体系,并提供可复现代码与工程化方案。(239字)
160 7
|
7天前
|
开发工具
【Application Insights】采样率对Function App日志收集的影响和解决方法
Azure Functions日志在Application Insights中缺失,主因是默认启用的采样功能(每秒限采20项遥测)。可通过`host.json`配置`excludedTypes`排除Request/Exception等关键类型,或查询`RetainedPercentage`确认采样状态。
141 6
|
7天前
|
人工智能 自然语言处理 安全
阿里云云部署OpenClaw集成钉钉
本文详解OpenClaw开源AI助手与钉钉的深度集成:支持群聊/单聊中自然语言交互,涵盖环境部署、钉钉应用创建、通道配置、机器人测试及多Agent绑定等全流程,并强调使用前须评估安全与合规性。
|
7天前
|
JSON Prometheus 监控
程序员进阶工程师必备技能之工程化与研发效率建设(五)
教程来源 https://aescc.cn/ 本节构建了完整的可观测性与效能度量体系:通过结构化JSON日志(含request_id/trace_id上下文)、Prometheus指标采集(HTTP/DB/业务维度)及OpenTelemetry分布式追踪;并集成DORA四大核心指标、开发者体验度量与可视化效能仪表板,实现从系统到团队的全栈监控与持续改进闭环。

热门文章

最新文章