关于 coding-principles
面向开发者和编码 Agent 的跨语言编码原则,涵盖可维护性、设计、错误、安全与重构。强调简单明确的改动,并在采用模式前核实仓库约定。
主要功能
- 01可维护性与简化原则
- 02函数和模块设计指导
- 03错误处理与传播
- 04安全和输入边界检查
- 05渐进式重构实践
适用场景
- 01规划可维护的代码改动
- 02审查函数与模块边界
- 03检查输入处理和访问控制
- 04通过回归检查进行重构
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ shinpr/ claude-code-workflows --skill coding-principles安装后在 Claude Code 中输入/coding-principles确认已加载。
附带文件references/security-checks.md
详细介绍
与语言无关的编码原则
核心理念
- 可维护性优先于速度:优先保障代码的长期健康,而非初期开发速度
- 简单优先:选择满足需求的最简单方案(YAGNI 原则)
- 设计收敛:以尽可能少引入新设计面的方式,交付当前所需结果。选择持久化状态、公共或跨边界契约、行为模式、可复用抽象或组件拆分时,所涉及的设计面已足以要求先完成完整的收敛流程。
- 明确胜于隐含:通过代码结构和命名清楚表达意图
- 删除胜于注释:删除未使用的代码,而不是将其注释掉
代码质量
持续改进
- 在已接受的结果和适用边界内重构相关代码,以降低变更风险或维护成本
- 逐步改进代码结构
- 保持代码库精简、聚焦
- 检查调用方后,删除已证实因所请求的变更而过时的代码;将不确定或超出范围的清理工作另行报告
可读性
- 使用源自问题领域的、有意义且描述性强的名称
- 名称使用完整单词;仅在缩写在该领域广为认可时才使用
- 使用描述性名称;单字母名称仅可用于循环计数器或广为人知的惯例(i、j、x、y)
- 将魔法数字和字符串提取为命名常量
- 尽可能让代码自我说明
函数设计
参数管理
- 当调用处的清晰度或协同演进需要时,将相关的位置参数归组到对象、结构体或字典中。若参数顺序符合惯例且调用仍然清晰,或外部/公共签名要求如此,则保留位置参数
- 除非迁移属于已接受的结果或适用工件,否则保留外部/公共签名
单一职责
- 每个函数都应做好一件事
- 当职责可独立变更或控制流不清晰导致当前单元更难理解、验证或复用时,提取函数;若提取会造成牵强的耦合,则保留连贯的领域流程
- 将复杂逻辑提取到独立且命名清晰的函数中
- 函数应保持单一抽象层级
函数组织
- 尽可能使用纯函数(无副作用)
- 将数据转换与副作用分开
- 使用提前返回来减少嵌套
- 当嵌套结构掩盖状态转换或决策归属时,使用提前返回或提取函数;若嵌套结构能更清晰地体现领域决策,则予以保留
错误处理
错误管理原则
- 始终处理错误:附带上下文记录日志,或显式传播错误
- 恰当地记录日志:包含便于调试的上下文
- 保护敏感数据:在日志中屏蔽或排除密码、令牌和个人身份信息(PII)
- 快速失败:尽早检测并报告错误
错误传播
- 使用符合语言习惯的错误处理机制
- 将错误传播到适当的处理层级
- 提供有意义的错误消息
- 重新抛出错误时包含相关上下文
依赖管理
通过参数化依赖实现松耦合
- 将外部依赖作为参数注入(类使用构造函数注入,过程式/函数式代码使用函数参数)
- 依赖抽象,而非具体实现
- 尽量减少模块间依赖
- 通过可模拟的依赖支持测试
参考代表性
采用前先验证参考内容
采用现有代码中的模式、API 或依赖项时:
- 如果参考示例仅涵盖附近文件 → 那么先检查相关仓库用法,确认该模式具有代表性,再采用
- 如果仓库中存在多种并行方案 → 那么确定占主流的模式并审慎选择——仅仅选择最近的方案是不够的
- 如果采用外部依赖项(库、插件、SDK) → 那么验证仓库范围内的用法和兼容性证据;如果这些证据无法确定所需版本,则记录尚未解决的版本决策,以及需要哪些证据才能敲定
- 如果遵循现有模式 → 那么在存在其他方案时,说明遵循该模式的原因(例如,与周边代码保持一致、避免破坏性变更、等待协调更新)
原则
附近的代码是调查的起点,而不是采用某种方案的充分依据。以其为范例之前,请先验证所参考的内容是否能代表仓库的惯例和当前最佳实践。
性能注意事项
优化方法
- 先测量:优化前先进行性能分析
- 关注算法:算法复杂度 > 微优化
- 使用适当的数据结构:根据访问模式进行选择
- 资源管理:妥善处理内存、连接和文件
何时优化
- 通过性能分析确定实际瓶颈后
- 性能问题可量化时
- 仅在识别出可量化的瓶颈后再优化,而不是在初始开发阶段优化
代码组织
结构原则
- 按功能分组:将相关代码放在一起
- 分离关注点:领域逻辑、数据访问、展示
- 命名保持一致:遵循项目惯例
- 模块内聚:模块内高内聚,模块间低耦合
文件组织
- 每个文件只承担一项主要职责
- 对相关函数/类进行逻辑分组
- 使用清晰且能体现架构的文件夹结构
- 当文件包含可独立变化的职责,或会显著增加导航、耦合或验证成本时,拆分该文件;如果拆分会造成不必要的耦合或导航成本,则保留内聚的文件
注释原则
默认做法:代码优先
名称、类型和结构是主要表达方式。只有当注释能传达代码本身无法表达的信息时,才值得保留。拿不准时,改进名称,而不是添加注释。
每条注释的判断标准
只有在回答以下某个问题时,注释才有必要:
- 原因:不明显决策背后的理由、权衡或限制
- 限制/边界情况:读者无法从代码中推断出的边界
- 公共 API 契约:导出接口的行为、输入和输出
每项决策只写一条注释。如果注释只是复述名称和控制流已经表达的内容,就删除注释并改进名称。
注释范围
- 按上述标准说明原因、限制和公共契约;其余内容(包括“如何实现”)交由名称和结构表达
- 将历史背景记录在版本控制的提交信息中,而不是注释中
- 删除已注释掉的代码(需要时从 git 历史中找回)
注释质量
- 注释应基于稳定的理由、限制和契约,而不是日期、版本或临时状态
- 修改代码时同步更新注释
- 使用规范的语法和格式
- 为未来的维护者撰写注释
重构方法
安全重构
- 小步进行:一次只做一项更改
- 保持可运行状态:确保测试持续通过
- 验证行为:每次更改后运行测试
- 渐进改进:每次只做足够且必要的最小改进
重构触发因素
- 代码重复(DRY 原则)
- 函数包含职责各自独立变化的部分,或控制流不清晰
- 条件逻辑复杂
- 命名或结构不明确
安全原则
安全默认设置
- 通过环境变量或专用密钥管理器存储凭据和机密
- 对所有数据库访问使用参数化查询(预处理语句)
- 使用语言或框架提供的成熟加密库
- 使用加密安全的随机数生成器生成安全关键值(令牌、ID、随机数)
- 使用标准协议对静态和传输中的敏感数据进行加密
输入和输出边界
- 在系统入口点验证所有外部输入的格式、类型和长度是否符合预期。外部输入包括请求数据、外部服务响应、模型或工具输出,以及写入方不可信或使用方需要存储本身无法提供的保证的存储数据
- 如果变更会改变这样一种边界:外部内容或模型输出可在该边界选择工具的操作、目标或目的地,请验证这些值不会超出已授予调用方的操作范围和访问权限
- 根据输出的呈现上下文(HTML、SQL、shell、URL)进行适当编码
- 错误响应仅返回调用方所需的信息;详细诊断信息记录在服务器端
访问控制
- 对所有处理用户数据或触发状态变更的入口点实施身份验证
- 对每次资源访问验证授权,而不只是在入口点验证
- 仅授予操作所需的权限(文件、数据库连接、API 范围)
- 对涉及身份或受保护资源的变更,优先审查身份验证和针对每项资源的授权
有关安全审查使用的具体检测模式,请参阅 references/security-checks.md。
评论
支持 Markdown