代码洁癖害我三年,直到我学会“脏着写”

胡芳
2025-12-25 21:40
阅读 324

五年前,我刚入行做后端开发时,总幻想写出教科书般的完美代码。变量命名要像诗,函数要短得像俳句,结构要优雅如芭蕾。结果呢?一个简单的用户注册接口,我改了三天还没上线——不是逻辑错,而是我觉得缩进不够对称。

后来项目赶上线,被逼着“先跑起来再说”,我才明白:代码不是艺术品,是工具。尤其在区块链这种快速迭代的领域,过度追求整洁反而拖慢交付。今天我就以一个老后端的身份,和你聊聊我是如何从“代码洁癖”中解脱出来的,并用一个真实的后端+区块链小项目带你实践“脏着写,快着改”的哲学。


为什么后端开发者特别容易染上代码洁癖?

后端不像前端有炫酷界面,也不像移动端有直观交互。我们的战场是 API、数据库、服务间调用——看不见摸不着。于是很多人把“代码整洁”当作唯一能证明自己专业的方式。

我当初学的时候,看到别人用三层嵌套 if 判断就浑身难受,非要用策略模式+工厂模式重构。结果呢?业务逻辑没跑通,倒是写了八百行抽象代码。

但现实很骨感:

  • 需求天天变:产品经理上午说要加用户等级,下午又说取消
  • 上线压力大:客户明天就要演示,你还在纠结要不要抽个 util 类?
  • 区块链更疯狂:智能合约一部署就不能改,但链下服务(后端)必须快速适配

所以,真正的专业不是“一次写对”,而是“快速试错 + 快速修正”。


环境准备:5分钟搭起你的“脏代码”试验田

别被吓到,我们只需要最基础的工具。记住:环境越简单,你越敢动手

所需工具清单

工具 版本 作用
Node.js >=18.x 运行 JavaScript 后端
npm / yarn 最新版 包管理器
VS Code 任意 编辑器(别装太多插件!)
Postman 任意 测试 API

💡 新手提示:不要花一整天配环境!如果 Node 装不上,用 Docker 一行命令搞定:
docker run -it --rm -v $(pwd):/app -w /app node:18 bash

初始化项目

打开终端,执行:

mkdir dirty-blockchain-api
cd dirty-blockchain-api
npm init -y
npm install express cors body-parser

这三行命令会创建一个最简后端项目,依赖只有 Express(Web 框架)、CORS(跨域支持)和 body-parser(解析请求体)。不要急着加 TypeScript、ESLint、Prettier——它们是洁癖的温床!


核心理念:什么是“脏代码”?它真的脏吗?

先破除一个迷思:“脏代码 ≠ 坏代码”。这里的“脏”,是指暂时放弃完美主义,优先让功能跑起来

洁癖 vs 实用:三种典型场景对比

场景 洁癖做法 实用做法 结果
处理用户输入 写校验类、异常处理、日志记录 直接 if (!req.body.name) return '缺名字' 后者当天上线
调用区块链 封装 Web3 客户端、错误重试、连接池 直接复制官方 demo 代码 后者两小时连上链
返回数据格式 定义 DTO、序列化器、中间件 res.json({ data: user, ok: true }) 后者前端立刻能用

我当初在做第一个区块链项目时,死活不肯直接用 web3.eth.getBalance(address),非要封装一层 “BlockchainService”。结果调试三天,发现只是钱包地址少了个 0x 前缀。

记住:在探索阶段,可读性 > 可维护性。等你知道需求稳定了,再重构不迟。


实战:用“脏代码”快速对接区块链余额查询

现在,我们用最糙的方式,写一个后端 API,让用户查自己的以太坊余额。目标:30 分钟内跑通

第一步:写一个“丑陋”但能跑的服务器

新建 server.js,粘贴以下代码(别管缩进!):

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();
app.use(cors());
app.use(bodyParser.json());

// 临时硬编码 Infura 节点(真实项目要用 .env)
const WEB3_PROVIDER = 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY';

// 直接引入 web3(别封装!)
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider(WEB3_PROVIDER));

// 一个超简单的路由
app.post('/get-balance', async (req, res) => {
  const { address } = req.body;
  
  // 不校验!假设前端传对了
  try {
    const balance = await web3.eth.getBalance(address);
    const eth = web3.utils.fromWei(balance, 'ether');
    res.json({ address, eth, success: true });
  } catch (err) {
    // 不细分错误类型!直接返回
    res.status(400).json({ error: err.message, success: false });
  }
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

🚨 注意:这里故意做了三件“不洁”之事:

  1. 硬编码 Infura key(实际应放环境变量)
  2. 无输入校验
  3. 错误处理粗糙

它能跑!这就是关键。

第二步:安装 Web3 并测试

npm install web3
node server.js

用 Postman 发 POST 请求到 http://localhost:3000/get-balance,Body 选 raw + JSON:

{
  "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}

(这是 Vitalik 的公开地址,放心查)

如果返回类似:

{
  "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "eth": "1234.56",
  "success": true
}

恭喜!你用“脏代码”完成了第一个区块链后端功能。


从“脏”到“净”:何时以及如何重构?

现在功能跑通了,是不是该立刻重构?不一定

重构决策树(文字版流程图)

功能是否稳定? → 否 → 继续用脏代码,快速迭代
                ↓ 是
是否会被多人调用? → 否 → 保持现状
                   ↓ 是
是否有重复逻辑? → 否 → 加注释即可
                  ↓ 是
                → 开始小步重构

在我的项目中,这个 /get-balance 接口一周内被改了四次(加 token 支持、加缓存、改返回字段)。如果第一天就封装,每次改都要动三层代码。

小步重构示例

假设现在需求稳定了,我们只做最小必要改进

  1. 抽出常量
// config.js
module.exports = {
  WEB3_PROVIDER: process.env.INFURA_URL || 'https://mainnet.infura.io/v3/xxx'
};
  1. 加基本校验
if (!address || !web3.utils.isAddress(address)) {
  return res.status(400).json({ error: 'Invalid address' });
}
  1. 拆出 service 函数(仅因逻辑复用)
// services/blockchain.js
async function getEthBalance(address) {
  const balance = await web3.eth.getBalance(address);
  return web3.utils.fromWei(balance, 'ether');
}

// routes/balance.js
const { getEthBalance } = require('../services/blockchain');

注意:不要为了“看起来整洁”而拆分!只有当同一段代码在两个地方出现时,才值得抽象。


新手常见问题解答

Q1:这样写会不会养成坏习惯?

不会。就像学画画先画草稿,再上色。区分“探索期”和“生产期” 是关键。你在本地开发、POC 阶段怎么脏都行;但合并到主分支前,至少做到:

  • 无硬编码敏感信息
  • 关键路径有基础错误处理
  • 函数不超过 50 行(防天书)

Q2:区块链后端和其他后端有什么不同?

最大区别:链上不可变,链下要灵活

  • 智能合约一旦部署,几乎不能改(除非预埋 upgrade 逻辑)
  • 但你的后端服务(API、数据库、定时任务)必须频繁调整以适配合约

所以我常说:合约要写得像石头,后端要活得像水

Q3:团队里有人嫌弃我的“脏代码”怎么办?

展示结果。如果能在 deadline 前交付,且 bug 不比别人多,多数人会闭嘴。实在不行,就说:“这是临时方案,下周重构”——然后真的下周重构。


下一步学习建议:在实战中平衡“快”与“稳”

如果你刚入门,我强烈建议按这个顺序练习:

  1. 先完成,再完美:用本文方法,做一个能跑的小项目(比如 NFT 余额查询)
  2. 引入基础工程化:加 .env 文件、简单日志、单元测试(只测核心逻辑)
  3. 学习设计原则:不是模式,而是 SOLID 中的单一职责、开闭原则
  4. 参与开源:看别人怎么在快速迭代和代码质量间找平衡

我的避坑指南:

  • 不要一上来就学微服务、DDD、Clean Architecture
  • 不要为“可能”的扩展性提前设计
  • 不要相信“一次写好”的神话——所有好代码都是改出来的

写在最后

五年前那个为缩进失眠的我,如今能坦然写出“脏代码”,不是因为降低了标准,而是明白了软件的本质是解决问题,不是展示技巧

尤其是在区块链这个充满不确定性的领域,后端开发者的价值不在于写出多优雅的代码,而在于快速连接链上与链下,让产品跑起来

所以,放下洁癖,大胆地“脏”一次吧。你的第一个版本可以丑,但一定要快。因为只有跑起来的代码,才有资格被优化。

附:本文所有代码已整理成 GitHub 仓库(搜索 dirty-blockchain-api-demo),欢迎 fork 并提交你的“脏”版本。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝