Series Clean Code Thực chiến #1: Định luật "WTF/phút" và Nghệ thuật Đặt tên
1. Thước đo chất lượng Code: Định luật "WTF/phút"
Khi bạn mở một file code cũ ra review (hoặc nhận bàn giao từ một đồng nghiệp đã nghỉ việc), chỉ có 2 kịch bản xảy ra:
- Bạn vừa cuộn chuột vừa lẩm bẩm: "Cái gì đây? Biến x này là gì? Tại sao lại if status == 2? WTF?"
- Bạn đọc code trôi chảy như đọc một cuốn truyện tiếng Việt.
Chất lượng của một hệ thống phần mềm được đo bằng số lần đồng nghiệp chửi thề (WTF) trong một phút khi đọc đoạn code đó. Code càng sạch, số lần WTF càng tiến về 0.
Nguyên tắc sống còn: Tỉ lệ Đọc/Viết trong lập trình là 10/1. Chúng ta tốn nhiều thời gian đọc code cũ để tìm chỗ sửa hơn là thời gian gõ dòng code mới. Do đó, viết code sạch không phải là làm màu, mà là để cứu lấy thanh xuân của chính bạn.
2. Nguyên tắc Tối thượng: Tên phải nói lên Ý định (Intention-Revealing)
Lỗi phổ biến nhất của lập trình viên là sợ gõ tên dài. Hệ quả là đẻ ra những biến vô nghĩa, buộc người đọc phải đi tìm comment hoặc lục lọi logic để hiểu biến đó làm gì.
Code bốc mùi (Bad Code):
$d = 0; // thời gian trôi qua tính bằng ngày
public function getThem() {
$list1 = [];
foreach ($this->theList as $x) {
if ($x[0] == 4) {
$list1[] = $x;
}
}
return $list1;
}
Nhìn đoạn code trên, bạn có hiểu nó làm gì không? Không thể! Dù không có thuật toán nào phức tạp, nhưng nó hoàn toàn thiếu "ngữ cảnh".
Clean Code: Hãy đặt bối cảnh đây là hệ thống Metro AFC.
$elapsedTimeInDays = 0;
public function getFlaggedTransactions() {
$flaggedTransactions = [];
foreach ($this->transactions as $transaction) {
if ($transaction->isSuspicious()) { // Đóng gói số 4 (magic number) vào một hàm có ý nghĩa
$flaggedTransactions[] = $transaction;
}
}
return $flaggedTransactions;
}
Giờ thì không cần một dòng comment nào, bạn vẫn biết hàm này làm nhiệm vụ "Lấy ra các giao dịch bị đánh dấu nghi ngờ".
3. Đừng bắt đồng nghiệp giải mã (No Mental Mapping)
Trong code, sự rõ ràng là vua. Đừng bao giờ chơi chữ, dùng từ lóng, hoặc viết tắt theo phong cách cá nhân.
- Có thể phát âm được: Nếu bạn không thể đọc thành tiếng, bạn không thể thảo luận nó với team. Đừng viết $genymdhms (Generate Year Month Day Hour Minute Second). Hãy viết $generationTimestamp.
- Dễ tìm kiếm (Searchable): Thử tưởng tượng bạn cần tìm lỗi liên quan đến số ngày tối đa được hoàn vé. Nếu bạn code if ($days > 7), bạn không thể search số 7 trong toàn bộ project được (vì nó sẽ ra hàng ngàn kết quả). Hãy dùng Hằng số (Constant): if ($days > self::MAX_DAYS_FOR_REFUND).
- Một từ cho một khái niệm: Nếu trong dự án, bạn lấy thông tin User bằng getUserInfo(), lấy danh sách Trạm bằng fetchStations(), lấy Giao dịch bằng retrieveTransactions()... bộ não của team sẽ bị quá tải. Hãy thống nhất một từ duy nhất (ví dụ: chỉ dùng get): getUser(), getStations(), getTransactions().
4. Đừng lạm dụng Tiền tố/Hậu tố rườm rà
Ngày xưa (thời C/C++), mọi người hay thêm kiểu dữ liệu vào tên biến, ví dụ: iTicketCount (số nguyên), arrTransactions (mảng). Ngày nay, các IDE hiện đại đã quá thông minh để báo cho bạn biết kiểu dữ liệu rồi.
Bad:
$strName = "Nguyễn Văn A";
$isStatusB = true;
class TransactionObject {}
Good:
$name = "Nguyễn Văn A";
$isSuccess = true; // Biến boolean nên bắt đầu bằng is, has, can, should...
class Transaction {} // Tên class phải là danh từ
Khởi đầu Clean Code chỉ đơn giản là việc chậm lại một nhịp trước khi bạn gõ tên một biến hay một hàm. Đặt tên đúng, bạn đã giải quyết được 50% gánh nặng bảo trì hệ thống cho tương lai.
Bạn có muốn ở bài tiếp theo, chúng ta đục sâu vào nguyên tắc thiết kế Hàm (Functions) — làm sao để viết một hàm thật ngắn gọn, chỉ làm đúng một việc duy nhất và không bao giờ gây "tác dụng phụ" không?
All rights reserved