CodeDocumentationSkill code-documentation

提供代码文档编写指南,包括JSDoc、Python docstrings、JavaDoc和内联注释,适用于不同编程语言和场景,强调最佳实践和资源链接。

架构设计 0 次安装 0 次浏览 更新于 3/3/2026

代码文档

概览

使用特定语言的标准创建清晰、全面的代码文档,如JSDoc、Python docstrings、JavaDoc和内联注释。

何时使用

  • 函数和类文档
  • JavaScript/TypeScript的JSDoc
  • Python的docstrings
  • Java的JavaDoc
  • 内联代码注释
  • 从代码生成API文档
  • 类型定义
  • 代码中的使用示例

JavaScript/TypeScript (JSDoc)

函数文档

/**
 * 计算包括税和折扣在内的总价。
 *
 * @param {number} basePrice - 税前和折扣前的基础价格
 * @param {number} taxRate - 以小数形式表示的税率(例如,0.08表示8%)
 * @param {number} [discount=0] - 可选的折扣金额
 * @returns {number} 税和折扣后的最终价格
 * @throws {Error} 如果basePrice或taxRate为负数
 *
 * @example
 * const price = calculateTotalPrice(100, 0.08, 10);
 * console.log(price); // 98
 *
 * @example
 * // 没有折扣
 * const price = calculateTotalPrice(100, 0.08);
 * console.log(price); // 108
 */
function calculateTotalPrice(basePrice, taxRate, discount = 0) {
  if (basePrice < 0 || taxRate < 0) {
    throw new Error('价格和税率必须非负');
  }
  return basePrice * (1 + taxRate) - discount;
}

/**
 * 从API获取用户数据,并包含重试逻辑。
 *
 * @async
 * @param {string} userId - 用户的唯一标识符
 * @param {Object} [options={}] - 额外选项
 * @param {number} [options.maxRetries=3] - 最大重试次数
 * @param {number} [options.timeout=5000] - 请求超时时间,以毫秒为单位
 * @returns {Promise<User>} 解析为用户对象的Promise
 * @throws {Error} 如果重试后用户仍未找到
 *
 * @typedef {Object} User
 * @property {string} id - 用户ID
 * @property {string} name - 用户的全名
 * @property {string} email - 用户的电子邮件地址
 * @property {string[]} roles - 用户角色数组
 *
 * @example
 * try {
 *   const user = await fetchUser('user123', { maxRetries: 5 });
 *   console.log(user.name);
 * } catch (error) {
 *   console.error('获取用户失败:', error);
 * }
 */
async function fetchUser(userId, options = {}) {
  const { maxRetries = 3, timeout = 5000 } = options;
  // 实现...
}

类文档

/**
 * 表示电子商务应用中的购物车。
 * 管理商品、计算总计和处理结账操作。
 *
 * @class
 * @example
 * const cart = new ShoppingCart('user123');
 * cart.addItem({ id: 'prod1', name: 'Laptop', price: 999.99 }, 1);
 * console.log(cart.getTotal()); // 999.99
 */
class ShoppingCart {
  /**
   * 创建一个新的购物车实例。
   *
   * @constructor
   * @param {string} userId - 拥有此购物车的用户ID
   * @param {Object} [options={}] - 配置选项
   * @param {string} [options.currency='USD'] - 货币代码
   * @param {number} [options.taxRate=0] - 以小数形式表示的税率
   */
  constructor(userId, options = {}) {
    this.userId = userId;
    this.items = [];
    this.currency = options.currency || 'USD';
    this.taxRate = options.taxRate || 0;
  }

  /**
   * 向购物车添加商品或增加已有商品的数量。
   *
   * @param {Product} product - 要添加的商品
   * @param {number} quantity - 要添加的数量(必须是正整数)
   * @returns {CartItem} 添加或更新后的购物车商品
   * @throws {Error} 如果数量不是正整数
   *
   * @typedef {Object} Product
   * @property {string} id - 商品ID
   * @property {string} name - 商品名称
   * @property {number} price - 商品价格
   *
   * @typedef {Object} CartItem
   * @property {Product} product - 商品详情
   * @property {number} quantity - 商品数量
   * @property {number} subtotal - 商品小计(价格 * 数量)
   */
  addItem(product, quantity) {
    if (!Number.isInteger(quantity) || quantity <= 0) {
      throw new Error('数量必须是正整数');
    }

    const existingItem = this.items.find(
      item => item.product.id === product.id
    );

    if (existingItem) {
      existingItem.quantity += quantity;
      existingItem.subtotal = existingItem.product.price * existingItem.quantity;
      return existingItem;
    }

    const newItem = {
      product,
      quantity,
      subtotal: product.price * quantity
    };
    this.items.push(newItem);
    return newItem;
  }

  /**
   * 计算包括税在内的总价。
   *
   * @returns {number} 含税的总价
   */
  getTotal() {
    const subtotal = this.items.reduce(
      (sum, item) => sum + item.subtotal,
      0
    );
    return subtotal * (1 + this.taxRate);
  }

  /**
   * 清空购物车中的所有商品。
   *
   * @returns {void}
   */
  clear() {
    this.items = [];
  }
}

类型定义

/**
 * 所有端点的API响应包装器
 *
 * @template T - 响应中的数据类型
 * @typedef {Object} ApiResponse
 * @property {boolean} success - 请求是否成功
 * @property {T} [data] - 响应数据(成功时存在)
 * @property {string} [error] - 错误消息(失败时存在)
 * @property {Object} [metadata] - 额外的响应元数据
 * @property {number} metadata.timestamp - 响应时间戳
 * @property {string} metadata.requestId - 唯一的请求ID
 */

/**
 * 用户认证凭证
 *
 * @typedef {Object} Credentials
 * @property {string} email - 用户电子邮件地址
 * @property {string} password - 用户密码(最少8个字符)
 */

/**
 * 列表端点的分页参数
 *
 * @typedef {Object} PaginationParams
 * @property {number} [page=1] - 页码(1索引)
 * @property {number} [limit=20] - 每页项目数(最多100)
 * @property {string} [sortBy='createdAt'] - 排序字段
 * @property {'asc'|'desc'} [order='desc'] - 排序顺序
 */

Python (Docstrings)

函数文档

def calculate_statistics(data: list[float], include_median: bool = True) -> dict:
    """
    计算数据集的统计量。

    计算数值列表的平均值、标准差、最小值、最大值,以及可选的中位数。

    参数:
        data: 要分析的数值列表。必须至少包含一个值。
        include_median: 是否计算中位数(默认:True)。
            对于大型数据集,设置为False以获得更好的性能。

    返回:
        包含以下键的字典:
        - 'mean' (float): 数据的算术平均值
        - 'std' (float): 标准差
        - 'min' (float): 最小值
        - 'max' (float): 最大值
        - 'median' (float): 中位数(如果include_median为True)
        - 'count' (int): 数据点数量

    引发:
        ValueError: 如果数据为空或包含非数值。
        TypeError: 如果数据不是列表。

    示例:
        >>> data = [1, 2, 3, 4, 5]
        >>> stats = calculate_statistics(data)
        >>> print(stats['mean'])
        3.0

        >>> # 不计算中位数以提高性能
        >>> large_data = list(range(1000000))
        >>> stats = calculate_statistics(large_data, include_median=False)

    注意:
        对于非常大的数据集,考虑将include_median设置为False
        因为中位数计算需要排序,这是O(n log n)的操作。

    参见:
        numpy.mean, numpy.std, statistics.median
    """
    if not isinstance(data, list):
        raise TypeError("数据必须是列表")
    if not data:
        raise ValueError("数据不能为空")

    mean = sum(data) / len(data)
    variance = sum((x - mean) ** 2 for x in data) / len(data)
    std = variance ** 0.5

    result = {
        'mean': mean,
        'std': std,
        'min': min(data),
        'max': max(data),
        'count': len(data)
    }

    if include_median:
        sorted_data = sorted(data)
        n = len(sorted_data)
        if n % 2 == 0:
            result['median'] = (sorted_data[n//2 - 1] + sorted_data[n//2]) / 2
        else:
            result['median'] = sorted_data[n//2]

    return result

类文档

class DatabaseConnection:
    """
    管理数据库连接,自动重试和连接池。

    这个类提供了数据库操作的上下文管理器接口,
    处理连接建立、查询执行和清理。

    属性:
        host (str): 数据库主机地址
        port (int): 数据库端口号
        database (str): 数据库名称
        max_retries (int): 最大连接重试次数
        timeout (int): 连接超时时间,以秒为单位
        pool_size (int): 连接池中的最大连接数

    示例:
        上下文管理器的基本使用:

        >>> with DatabaseConnection('localhost', 5432, 'mydb') as db:
        ...     results = db.execute('SELECT * FROM users')
        ...     for row in results:
        ...         print(row)

        自定义配置:

        >>> config = {
        ...     'max_retries': 5,
        ...     'timeout': 30,
        ...     'pool_size': 10
        ... }
        >>> db = DatabaseConnection('localhost', 5432, 'mydb', **config)

    注意:
        总是使用这个类作为上下文管理器,以确保正确的
        连接清理。不推荐手动连接管理。

    警告:
        连接不是线程安全的。对于并发操作,请创建单独的实例。
    """

    def __init__(
        self,
        host: str,
        port: int,
        database: str,
        username: str = None,
        password: str = None,
        max_retries: int = 3,
        timeout: int = 10,
        pool_size: int = 5
    ):
        """
        初始化一个新的数据库连接管理器。

        参数:
            host: 数据库服务器主机名或IP地址
            port: 数据库服务器端口(通常PostgreSQL为5432)
            database: 要连接的数据库名称
            username: 数据库用户名(默认:来自环境)
            password: 数据库密码(默认:来自环境)
            max_retries: 连接失败时的最大重试次数
            timeout: 连接超时时间,以秒为单位
            pool_size: 连接池中的最大连接数

        引发:
            ValueError: 如果host、port或database无效
            ConnectionError: 如果无法建立初始连接
        """
        self.host = host
        self.port = port
        self.database = database
        self.max_retries = max_retries
        self.timeout = timeout
        self.pool_size = pool_size
        self._connection = None
        self._pool = []

    def execute(self, query: str, params: tuple = None) -> list:
        """
        执行SQL查询并返回结果。

        参数:
            query: SQL查询字符串,可选参数占位符
            params: 参数化查询的参数值元组

        返回:
            以列名作为键的字典形式的行列表

        引发:
            QueryError: 如果查询执行失败
            ConnectionError: 如果数据库连接丢失

        示例:
            >>> db = DatabaseConnection('localhost', 5432, 'mydb')
            >>> results = db.execute(
            ...     'SELECT * FROM users WHERE age > %s',
            ...     (18,)
            ... )
        """
        pass

    def __enter__(self):
        """进入上下文管理器,建立数据库连接。"""
        self.connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """退出上下文管理器,关闭数据库连接。"""
        self.close()

模块文档

"""
用户认证和授权模块。

这个模块提供用户认证、密码散列、令牌生成和权限检查的功能。它支持包括JWT令牌、API密钥和OAuth2在内的多种认证方法。

特性:
    - 使用bcrypt进行安全的密码散列
    - JWT令牌生成和验证
    - 基于角色的访问控制(RBAC)
    - OAuth2集成(Google、GitHub)
    - 双因素认证(2FA)

示例:
    基本认证:

    >>> from auth import authenticate, generate_token
    >>> user = authenticate('user@example.com', 'password123')
    >>> token = generate_token(user)

    密码散列:

    >>> from auth import hash_password, verify_password
    >>> hashed = hash_password('password123')
    >>> is_valid = verify_password('password123', hashed)

属性:
    TOKEN_EXPIRY (int): 默认令牌有效期,以秒为单位
    HASH_ROUNDS (int): bcrypt散列轮数
    MAX_LOGIN_ATTEMPTS (int): 最大失败登录尝试次数,超过将锁定

待办:
    * 添加对SAML认证的支持
    * 实现刷新令牌轮换
    * 添加登录尝试的速率限制

注意:
    这个模块需要安装bcrypt和PyJWT包。
"""

TOKEN_EXPIRY = 3600  # 1小时
HASH_ROUNDS = 12
MAX_LOGIN_ATTEMPTS = 5

Java (JavaDoc)

/**
 * 管理系统中的用户账户和认证。
 * <p>
 * 这个类提供创建、更新和删除用户账户的方法,以及认证用户和管理会话。
 * </p>
 *
 * <h2>使用示例:</h2>
 * <pre>{@code
 * UserManager manager = new UserManager();
 * User user = manager.createUser("john@example.com", "password123");
 * boolean authenticated = manager.authenticate(user.getId(), "password123");
 * }</pre>
 *
 * @author John Doe
 * @version 2.0
 * @since 1.0
 * @see User
 * @see Session
 */
public class UserManager {
    /**
     * 使用指定的凭证创建新用户账户。
     *
     * @param email    用户电子邮件地址(必须有效且唯一)
     * @param password 用户密码(最少8个字符)
     * @return 新创建的User对象
     * @throws IllegalArgumentException 如果电子邮件无效或已存在
     * @throws PasswordTooWeakException 如果密码不符合要求
     * @see #updateUser(String, User)
     * @see #deleteUser(String)
     */
    public User createUser(String email, String password)
            throws IllegalArgumentException, PasswordTooWeakException {
        // 实现
    }

    /**
     * 使用他们的凭证认证用户。
     *
     * @param userId   唯一用户标识符
     * @param password 用户密码
     * @return 如果认证成功返回{@code true},否则返回{@code false}
     * @throws UserNotFoundException 如果用户不存在
     * @deprecated 使用{@link #authenticateWithToken(String, String)}代替
     */
    @Deprecated
    public boolean authenticate(String userId, String password)
            throws UserNotFoundException {
        // 实现
    }
}

内联注释最佳实践

// ❌ 不好:明显的注释
// Increment counter by 1
counter++;

// ✅ 好:解释为什么,而不是做什么
// Account for 1-based indexing in the API response
counter++;

// ❌ 不好:过时的注释
// TODO: Fix this bug (written 2 years ago)
function processData() {}

// ✅ 好:带有上下文的可操作注释
// TODO(john, 2025-01-15): Refactor to use async/await
// See GitHub issue #1234 for performance benchmarks
function processData() {}

// ❌ 不好:注释掉的代码
// const oldCalculation = (a, b) => a + b;
// const anotherOldThing = 42;

// ✅ 好:移除死代码,使用版本控制代替

// ❌ 不好:多余的注释
/**
 * Gets the user name
 */
function getUserName() {
  return this.name;
}

// ✅ 好:添加有价值的上下文
/**
 * Returns display name formatted according to user's locale preferences.
 * Falls back to username if display name is not set.
 */
function getUserName() {
  return this.displayName || this.username;
}

最佳实践

✅ 做

  • 全面记录公共API
  • 包括使用示例
  • 记录参数和返回值
  • 指定抛出的异常/错误
  • 使用特定语言的标准(JSDoc、docstrings等)
  • 保持注释更新
  • 注释“为什么”而不是“做什么”
  • 包括边缘情况和陷阱
  • 添加相关函数的链接
  • 记录类型定义
  • 使用一致的格式

❌ 不做

  • 在注释中陈述显而易见的内容
  • 留下注释掉的代码
  • 编写误导性的注释
  • 对于复杂函数省略示例
  • 使用模糊的参数描述
  • 忘记在代码更改时更新文档
  • 过度注释简单代码

资源