务实编程

写给追求稳定与效率的程序员 · 少记、实用、可维护

“能稳定运行的普通写法,远比花哨但记不住的新特性重要。” —— 这不是保守,而是被无数工程验证过的智慧。本文不谈虚的,只记录真正让代码容易理解、容易维护、不易出错的务实原则。面向专业程序员,不解释基础语法,不写废话注释。

一、命名 · 让代码自己说话

变量名多打几个字符不会让程序变慢,但少打几个字符会让维护者想打人。好的命名就是最好的注释。

// ❌ 不知所云
var a = GetData();
var b = a.Where(x => x.Status == 1).ToList();

// ✅ 自解释
var allOrders = GetOrders();
var activeOrders = allOrders.Where(order => order.Status == OrderStatus.Active).ToList();

例外:循环变量 i, j, k 和极短作用域的临时变量 tmp 可保留传统。

二、函数长度 · 一屏原则

一个函数不应超过一屏 (40~50行)。超过就意味着它做了太多事,拆分是义务,不是重构。

// ❌ 巨型函数,注释分段也救不了
public void ProcessOrder(Order order) {
    // 验证... 20行
    // 价格计算... 25行
    // 数据库保存... 20行
}

// ✅ 职责单一,函数名即文档
public void ProcessOrder(Order order) {
    Validate(order);
    CalculatePrice(order);
    Save(order);
    Notify(order);
}

三、条件判断 · 早返回,少嵌套

嵌套超过3层,大脑开始烧毁。用卫语句提前返回异常路径,主干保持平坦。

// ❌ 箭头型代码
if (user != null) {
    if (user.IsActive) {
        if (user.HasPermission) {
            // 核心逻辑
        }
    }
}

// ✅ 卫语句,清晰直接
if (user == null) return;
if (!user.IsActive) return;
if (!user.HasPermission) return;
// 核心逻辑

四、重复代码 · 三则重构

同一段代码出现3次,必须抽取函数。复制粘贴是技术债务的源头。

// 出现两次可能还能忍,第三次必须抽离
decimal CalculateTotal(Order order) => order.Items.Sum(i => i.Price * i.Quantity);

五、魔法数字 · 用常量说话

代码里出现原始数字必须给名字,即使你认为自己记得住。

// ❌ 幽灵数字
if (age >= 18) { }
Thread.Sleep(3000);

// ✅ 语义化常量
const int VotingAge = 18;
Thread.Sleep(TimeSpan.FromSeconds(3));

六、注释 · 只写“为什么”,不写“是什么”

专业程序员的代码本身就是注释。注释的唯一价值是解释业务规则/陷阱/临时方案

// ❌ 废话注释
// i加1
i++;

// ✅ 解释原因
// 等待3秒,确保主从同步完成
Thread.Sleep(3000);

// 使用 > 而不是 >= ,因为状态2表示“待审核”,不应该包含
if (status > OrderStatus.Pending) { }

七、错误处理 · 不吞异常

不确定怎么处理的异常,就不要catch。吞掉异常会让程序在错误状态里狂奔,比崩溃更可怕。

// ❌ 沉默的灾难
try { DoSomething(); } catch { }

// ✅ 只处理明确可恢复的异常
try {
    DoSomething();
} catch (SpecificException ex) {
    LogAndRecover(ex);
}
// 其他异常向上抛出,由上层决策

八、日志 · 让人看懂发生了什么

日志必须包含上下文:谁、做了什么、影响什么对象、结果如何。不写只有你自己才懂的暗号。

// ❌ 无效日志
Log("开始处理");

// ✅ 可追溯
Log($"用户 {userId} 处理订单 {orderId},耗时 {elapsedMs}ms,状态 {status}");

九、一致性 · 比“正确”更重要

在已有项目里,保持一致 优先于个人偏好。先看周围代码怎么写,然后跟随,不要搞特殊。

// 项目里大家都用 userList,你就别发明 userArr
var userList = GetUsers();   // 团队风格
var userList = GetUsers();   // 跟随,不要写 lstUser

十、专业程序员的注释观

一行行解释代码在做什么,是对同事的侮辱。注释只用于:


十一、务实工具箱 · 少即是多

下面这张表是日常编码最实用的「决策速查」。

场景务实原则
变量命名名字长度和作用域成正比,全局/长作用域命名要详细
函数拆分看到注释“步骤1/步骤2” → 立刻拆成小函数
条件复杂度if嵌套 > 2层 → 改用早返回或提取谓词函数
重复检测Copy-paste 两次就警惕,三次必须抽象
异常处理只捕获你能处理的,否则让调用方决定
代码格式化团队统一 .editorconfig / 格式化工具,不要手动对齐
review重点命名、嵌套、重复、异常吞噬、魔法数字

十二、关于“新特性”的态度

语言新特性是工具,不是勋章。记不住的就用旧写法,稳定优先。例如 C# 的 out var 内联声明,可用也可不用,对性能无影响,选团队最容易读的版本。

// 两种都可以,选你团队一看就懂的
int v;
if (dict.TryGetValue(key, out v)) { }

// 或者内联版本,但没必要刻意追求
if (dict.TryGetValue(key, out int v)) { }

原则:你写的代码三个月后大概率由另一个人维护,降低认知负担是最大的仁慈。

十三、给务实者的最终检查清单

代码是写给人看的,只是恰好能被机器执行。
坚持务实,保持简单。不炫技,不设限。