Tôi có một bạn - anh ấy vào công ty mới, nhận được task "đọc code và fix bug". Anh ấy mở file thứ nhất và thấy 5000 dòng trong một class duy nhất. Không biến tên có ý nghĩa, không comment, chỉ toàn các hàm có tên kiểu process(), handle(), utils(). Ba ngày sau, anh ấy gửi mail xin nghỉ.
Cái chết của một lập trình viên không phải do stack overflow, mà do code stack không thể hiểu.
Clean code không phải là một tùy chọn – nó là sự khác biệt giữa một dự án bạn có thể bảo trì với một dự án khiến bạn tỉnh dậy lúc 3 sáng vì bug lạ. Và đương nhiên, nó cũng là hiệu suất công việc của cả team.
Tại sao code "bình thường" lại trở thành ác mộng?
Hầu hết các lập trình viên đều viết code với suy nghĩ "nó chạy được là được". Nhưng đây là sự thật đau lòng: bạn viết code 1 lần nhưng đọc code 10 lần. Nếu phải dành 30 phút để hiểu một function 10 dòng, team sẽ mất hàng tháng chỉ để bảo trì mà không thêm feature mới.
Google từng công bố rằng họ dành 20% thời gian engineering cho việc refactor code. Không phải vì họ yêu thích refactor, mà vì họ biết: code xấu = chi phí cao = bug nhiều = khách hàng tức.
Các nguyên tắc không negotiable
1. Đặt tên có ý nghĩa (không phải tên "ngắn gọn")
```javascript
// Cỏm
const d = new Date();
const p = getUserData(id);
const fn = () => { /* 20 dòng */ };
Tôi đã từng thấy code sử dụng a, , làm tên biến. Không, nó không ngắn hơn gì cả – khi bạn viết quanh co hơn để hiểu tên biến, bạn lãng phí thời gian. Đặt tên mà bất cứ ai đọc cũng hiểu ngay ý nghĩa.
Chia sẻ bài viết
Bài viết liên quan
Bạn cần tư vấn về công nghệ?
Đội ngũ Idflow luôn sẵn sàng hỗ trợ bạn trong hành trình chuyển đổi số.
Một hàm nên chỉ làm một điều, và làm nó tốt. Nếu bạn không thể mô tả function trong một câu, nó đã quá phức tạp.
```javascript
// Hàm lớn – khó test, khó sửa
const processOrder = (order) => {
// kiểm tra
// tính toán
// cập nhật database
// gửi email
// log
// ...
};
// Tách nhỏ
const validateOrder = (order) => { /* chỉ kiểm tra */ };
const calculateTotal = (order) => { /* chỉ tính */ };
const saveOrder = (order) => { /* chỉ lưu */ };
const notifyCustomer = (order) => { /* chỉ gửi */ };
```
Lợi ích bonus: khi cần fix bug, bạn biết chính xác phần nào có vấn đề thay vì tìm cách trong 200 dòng code.
3. Giảm thiểu nested logic
Mỗi lớp lồng nhau = mỗi cơ hội để bạn bị lạc:
```javascript
// Sử dụng early return
const getDiscount = (user) => {
if (!user) return 0;
if (!user.isPremium) return 0;
if (user.memberSince > 365) return 20;
return 10;
};
// Thay vì
const getDiscount = (user) => {
if (user) {
if (user.isPremium) {
if (user.memberSince > 365) {
return 20;
} else {
return 10;
}
} else {
return 0;
}
} else {
return 0;
}
};
```
4. Về comment – viết ít hơn bạn nghĩ
Comment tốt giải thích tại sao, không phải cái gì. Code nên tự giải thích bản thân nó.
```javascript
// Cỏm
// Lặp qua user
for (let i = 0; i < users.length; i++) {
// cộng tuổi
totalAge += users[i].age;
}
// Nếu cần comment
// Dùng reduce thay vì forEach để tránh side effects, dễ test hơn
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
```
Những insight ít ai nói đến
Error handling không phải tùy chọn. Hôm nay bạn test trên máy của mình với data hoàn hảo. Ngày mai trên production, một user nhập số phone có dấu, hệ thống crash. Luôn luôn assume input có thể sai.
Performance tôi cũng care, nhưng clarity trước tiên. Một cái for loop dễ hiểu tốt hơn một reduce khó hiểu nhưng nhanh 0.001ms. Ship tính năng đúng hạn và khách hàng hạnh phúc > code tối ưu hóa mà chỉ bạn hiểu.
Test code cũng là code. Nếu test code bẩn, bạn không tin vào test. Nếu không tin test, bạn sợ refactor. Nếu sợ refactor, code tồi tệ hơn. Vòng tròn địa ngục.
Tools và thói quen hàng ngày
ESLint + Prettier: Không cần tranh luận về style. Setup một lần, quên nó đi.
Pre-commit hooks: Dùng Husky để chắc chắn code bạn commit đã pass linter trước khi push.
Code review: Tốt nhất là review code trước khi merge. Tệ nhất là review sau (hoặc không review gì cả).
Tại các công ty Việt Nam như Grab, Tiki, họ có standard code review chặt chẽ đúng vì lý do này.
Kết luận không phải kết luận
Clean code không được dạy ở trường đại học. Nó là skill bạn học từ những lần code xấu đã đốt cháy project, hoặc từ việc bảo trì code của người khác. Mỗi lần bạn viết code, hãy tự hỏi: "Liệu tôi có thể hiểu code này sau 6 tháng?"
Nếu câu trả lời là không, refactor ngay. Lãi suất của technical debt rất cao.
Các đội ở Idflow Technology hiểu rõ triết lý này – từ đó họ xây dựng những sản phẩm có thể scale và bảo trì lâu dài.