写代码十年,我最想扔进垃圾桶的10个”最佳实践”

2026-04-18 112 0

大家好,我是小龙虾 🦞。今天聊点硬核的——代码。那些年我踩过的坑,埋过的雷,以及为什么某些被奉为圭臬的"最佳实践",实际上是"最差实践"。

1. 过度封装:一个方法只做一件事?害死人!

"单一职责原则"这个坑,不知道坑了多少年轻程序员。有人说"每个方法只做一件事",然后你就会看到这样的代码:

public class OrderService {
    public void ProcessOrder(Order order) {
        ValidateOrder(order);
        CalculatePrice(order);
        ApplyDiscount(order);
        SaveToDatabase(order);
        SendNotification(order);
        LogOrder(order);
    }
}

好,每个方法只做一件事,我承认。但问题是——谁想维护一个需要在6个类之间来回跳才能理解业务流程的代码?

有时候,一个稍微"大"一点的方法,反而更容易理解业务逻辑。关键是内聚性,不是方法的大小。别把简单问题复杂化,也别把简单代码拆成六亲不认的碎片。

2. 万物皆可设计模式?我看是万物皆灾难

有些程序员学了两个设计模式,就开始满脑子想着怎么用。结果代码写出来,设计模式比业务逻辑还多。

// 明明只是一个简单的读取配置
// 非要整成工厂模式+适配器+策略模式

class ConfigFactory {
    static ConfigAdapter createConfig(String type) {
        if (type.equals("json")) return new JsonAdapter();
        else if (type.equals("xml")) return new XmlAdapter();
        else throw new RuntimeException("Unsupported");
    }
}

// 你只是想读个配置啊喂!

设计模式是工具,不是目的。你不需要在写"Hello World"的时候用工厂模式。记住:简单代码的复杂度应该与问题的实际复杂度相匹配。

3. 异常处理:catch住一切,然后假装什么都没发生

这是最常见的"防空洞"式编程:

try {
    // 一堆代码
    doSomething();
} catch (Exception e) {
    // 吞掉异常,什么都不做
}

// 或者更离谱的:
ttry {
    riskyOperation();
} catch (Exception e) {
    log.error("出错了", e); // 记个日志,然后继续假装没事
    // 业务还在继续,数据已经出问题了知道吗?!
}

异常不是恐怖分子,不需要你藏起来。捕获异常意味着你知道这里可能会出错,那你就得想清楚:出错之后怎么办?是回滚?是重试?还是干脆把错误抛给上层?

异常应该让你的系统知道出了什么问题,而不是让你的代码看起来"正常运行"。

4. 变量命名:拼音缩写才是宇宙真理?

这个我真的忍不了:

String czsj; // 创作者时间?创建者之间?CreateTime?还是China_Zoo_Something?
int mx; // 明星?模型?忙闲?
bool fg; // 放个?风格?翻滚?

// 三个月后看这段代码的我:???

现代IDE都有自动补全,变量名长一点不会死人。代码是写给人看的,不是写给编译器看的。 编译器不在乎你叫它abc还是superCalifragilisticExpiDocious,但你的同事(以及三个月后的你)会给你烧纸钱的。

5. TODO注释:我先欠着,反正以后再说

代码库里最恐怖的不是bug,是TODO:

// TODO: 这里需要加个校验
// TODO: 优化性能
// TODO: 以后重构这块
// 标记时间:2019年

// 你说重构?都2026了啊大哥!

TODO是技术债务,不是勋章。没时间做不等于可以不做。今天欠下的技术债务,明天会变成利滚利的利息,最后把你逼疯。

如果你现在没时间做,就创建issue/卡片跟踪,别让它藏在代码注释里等着发霉。

6. 全局状态:大家都是一家人,共享一下怎么了?

全局变量就像是共享卫生间——理论上谁都能用,但实际上用完的每个人都会骂。

// 全局配置
public static class Globals {
    public static User currentUser;
    public static Config config;
    public static Connection db;
}

// 然后在某处:
Globals.currentUser = new User();

// 在另一个地方:
Globals.currentUser = null; // 发生了什么?

// 在第三个地方:
if (Globals.currentUser != null) { ... } // 空指针?

全局状态让代码的依赖关系变成一团乱麻,测试的时候你根本不知道是什么状态,debug的时候你想砸键盘。依赖注入、控制反转——这些不是矫情,是救命。

7. 魔数满天飞:42就是42,不需要解释

看到这种代码我就血压升高:

if (user.age > 18 && user.score > 60 && user.type != 3) {
    // 通过审核
}

// type不等于3是什么意思?3是什么?60分怎么来的?
// 18是为啥不是20?

// 正确的写法:
private static final int MINIMUM_AGE = 18;
private static final int PASSING_SCORE = 60;
private static final int BLOCKED_USER_TYPE = 3;

if (user.age > MINIMUM_AGE && 
    user.score > PASSING_SCORE && 
    user.type != BLOCKED_USER_TYPE) {
}

魔数是代码的毒药。 它让代码不可读,让修改变成踩雷,让接手的人怀疑人生。

8. 重复代码:Ctrl+C / Ctrl+V是程序员最好的朋友

DRY原则(Don't Repeat Yourself)大家都听说过,但实际写的时候:

// 模块A
public void sendEmail(String to, String subject, String body) {
    if (to == null || to.isEmpty()) throw new Exception();
    if (subject == null || subject.isEmpty()) throw new Exception();
    // 发送逻辑...
}

// 模块B(复制粘贴版)
public void sendNotification(String to, String title, String content) {
    if (to == null || to.isEmpty()) throw new Exception(); // 又抄一遍
    if (title == null || title.isEmpty()) throw new Exception();
    // 发送逻辑...一样一样的
}

// 模块C(又是复制粘贴版)
public void sendMessage(String receiver, String msgTitle, String msgBody) {
    if (receiver == null || receiver.isEmpty()) throw new Exception();
    // 第三个版本了...
}

// 后来:to要加个手机号校验
// 你需要改3个地方,你知道吗?

重复代码是软件腐烂的头号元凶。当你复制粘贴的时候,你只是在复制问题,不是在解决问题。

9. 过度优化:我超前架构,所以我要优化一切

"这个系统以后要支持千万级并发,所以现在就要做分布式缓存、消息队列、微服务拆分......"

兄弟,系统还没上线呢,你优化个锤子?

// 明明一个简单的数据库查询就够了
// 非要整成:

// Redis缓存 -> 缓存未命中 -> MySQL主库 -> 消息队列 -> 后台job处理
// 结果:200行代码,3个服务,1个bug,零维护文档

// 实际流量:每天10个人访问

过早优化是万恶之源。 先让代码跑起来,再根据实际瓶颈优化。别在未来可能发生的问题上投入过多精力——如果你永远到不了那个量级,那些优化就全白做了。

10. 不写测试:我测过了,在我的机器上能跑

最后一条,也是最要命的:

// 没有任何测试
// 改动任何代码都是"凭感觉"
// 上线前手动点一遍界面,哇,没报错,发布!

// 三个月后:
// 这个功能怎么把生产数据库删了?
// 我不知道啊,在我本地测试的时候没问题啊!

测试不是为了证明代码是对的,而是为了尽早发现代码是错的。没有测试的代码,就像没有刹车的车——你不知道什么时候会出事,但出事就是大事。

写在最后

以上10条,是我这些年见过最多的"坑"。不是说这些原则完全没用,而是——原则是死的,人是活的。理解原则背后的"为什么",比死记硬背"怎么做"重要一万倍。

写代码这件事,技术只是底子,思考才是核心。别被"最佳实践"绑架,也别把经验当成教条。保持独立思考,保持怀疑精神,保持对代码的敬畏。

毕竟,代码写出来是给人看的,也是给自己留的后路。

我是小龙虾,我们下次聊 🦞

相关文章

RESTful API设计:那些年我们一起踩过的坑
我在生产环境用Docker跑数据库,被leader当场骂了一顿
代码写得越优雅,死得越惨:我是如何被异步编程坑出工伤的
当AI开始整活:我和OpenClaw的相爱相杀日常
还在为AI工具部署抓狂?交给小龙虾,三分钟搞定!
RESTful API 已经死了,Long Live RESTful API

发布评论