能写出复杂算法的程序员很多,但能把变量起个好名字的人少得可怜。
更扎心的是——大多数人压根不觉得这是个问题。
他们觉得命名只是"形式主义",只要代码能跑,叫什么都行。直到某天接手三个月前自己写的代码,盯着data1、temp、utils这些鬼东西抓狂时,才意识到:
命名烂的代码,就是给未来的自己埋坑。
但今天我要说的更狠:命名能力,直接暴露你的架构水平。
我接手过一个React项目,看到这样的代码:
// 💩 烂命名版本
const data = useFetch();
const handler = () => {...};
const flag = useCheck();
function Component({ value, onChange }) {
// ...
}
我当时的反应:
data是啥数据?用户列表?订单详情?配置项?handler处理什么?点击?提交?校验?flag检查什么条件?权限?状态?表单合法性?value和onChange是通用prop还是特定业务逻辑?这不是代码,这是密码学挑战。
现在看重构后的版本:
// ✅ 好命名版本
const userProfile = useUserProfile(userId);
const submitOrderHandler = () => {...};
const isUserEligibleForDiscount = useDiscountEligibilityCheck(userId);
function PriceDisplayCard({
currentPrice,
onPriceUpdate
}) {
// ...
}
同样的逻辑,但每个名字都在回答:
这就是设计决策的可视化。
每一个命名,都是你对系统边界、职责划分、数据流向的判断。
很多人觉得"这个东西不好起名字"是正常现象。
错了,这恰恰是设计有问题的信号。
我总结了三种典型的"命名困境":
// 🚨 警告信号
function handleUserDataAndUpdateUIAndSendAnalytics() {
// 一个函数干了三件事
}
// ✅ 拆分后
function updateUserProfile(userData) {...}
function refreshProfileUI() {...}
function trackProfileUpdate(eventData) {...}
规律:当你需要用And连接多个动词时,说明这个函数违反了单一职责原则。
// 🚨 警告信号
const userDataTemp = {...};
const userDataFinal = {...};
const userDataProcessed = {...};
// ✅ 明确阶段职责
const rawUserInput = {...}; // 原始输入
const validatedUserData = {...}; // 校验后
const normalizedUserProfile = {...}; // 规范化后
规律:temp、final、new这类形容词,通常意味着你没想清楚数据的生命周期。
// 🚨 警告信号
const manager = useManager();
const helper = useHelper();
const service = useService();
// ✅ 明确业务语义
const cartManager = useShoppingCart();
const priceCalculator = usePriceCalculation();
const paymentGateway = usePaymentService();
规律:Manager、Helper、Service是编程中的"口头禅",暴露你对业务理解的浅薄。
我让两组开发者分别维护功能相同的代码库:
6个月后统计:
为什么?因为好名字自带文档属性。
// A组风格:需要注释解释
const x = 0.15; // 折扣率
const y = calculateFn(x); // 计算最终价格
// B组风格:名字即文档
const discountRate = 0.15;
const finalPrice = applyDiscount(discountRate);
注释会过期,但名字跟着代码走。
当你把x改成discountRate时,你不只是改了个名字——你是在给系统注入语义。
// ❌ 技术导向
const dto = fetchData();
const vo = transform(dto);
// ✅ 业务导向
const orderSummary = fetchOrderSummary();
const orderDisplay = formatForDisplay(orderSummary);
为什么:产品经理看得懂的名字,才是好名字。
// ❌ 不对称
const startServer = () => {...};
const stopServing = () => {...};
// ✅ 对称
const startServer = () => {...};
const stopServer = () => {...};
为什么:对称性让人一眼看出配对关系,降低认知负担。
// ✅ 好的梯度
for (let i = 0; i < 10; i++) { ... } // 局部短变量
const userId = getUserId(); // 模块级中等长度
const authenticatedUserSessionToken = ...; // 全局长变量
为什么:作用域越大,名字越需要自解释。
禁用清单:
data → 用具体数据类型(users、config)info → 用明确信息类型(profile、metadata)handle → 用具体动作(submit、validate)manager → 用具体职责(coordinator、factory)// ❌ 无法念出来
const usrLstMgr = ...;
// ✅ 可以念出来
const userListManager = ...;
为什么:代码是要在Code Review时讨论的,念不出来的名字没法交流。
// ❌ 过度缩写
const u = getU();
const p = calcP(u);
// ✅ 该长就长
const user = getUser();
const price = calculatePrice(user);
IDE有自动补全,多打几个字母不会死。
// ❌ 匈牙利命名法遗毒
const userArray = [];
const priceNumber = 0;
const isActiveBoolean = false;
// ✅ 让TypeScript干这活
const users: User[] = [];
const price: number = 0;
const isActive: boolean = false;
类型系统已经告诉你类型了,名字里再写一遍是浪费。
// ❌ 啰嗦
class User {
userName: string;
userAge: number;
userEmail: string;
}
// ✅ 简洁
class User {
name: string;
age: number;
email: string;
}
已经在User类里了,还写userXxx干嘛?
我观察过几个10年+经验的架构师写代码的过程,发现一个规律:
他们80%的时间不是在写新代码,而是在重命名。
useData改成useUserPreferencesComponent改成UserAvatarWithStatusonClick改成onSubmitForm一开始我不理解,后来才懂:
他们不是在改名字,他们是在持续澄清系统的语义边界。
每一次重命名,都是在回答:
命名,就是架构的草图。
如果你现在正在纠结一个名字起不好——
别急着写代码,先画一张图。
把这个东西的输入、输出、依赖、职责画出来。
如果画不清楚,说明你自己都没想明白,代码写出来也是一团浆糊。
好的命名,来自清晰的设计。 清晰的设计,来自深度的思考。
所以下次当你觉得"命名好难"时——
恭喜你,你正站在成为更好的开发者的门槛上。
因为能给东西起个好名字的人,才真正理解这个系统。