📖 Summary of The Art of Readable Code
1. Code Should Be Easy to Understand
Ý chính: Giảm thời gian để hiểu code.\
Code dễ đọc quan trọng hơn code ngắn.\
Ví dụ:
// Khó hiểu return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent); // Rõ ràng hơn if (exponent >= 0) { return mantissa * (1 << exponent); } else { return mantissa / (1 << -exponent); }
2. Packing Information into Names
Tên là comment ngắn.\
Dùng từ cụ thể, rõ ràng.\
Thêm đơn vị hoặc thuộc tính nếu quan trọng.\
Ví dụ:
# Không tốt def GetPage(url): ... # Tốt hơn def FetchPage(url): ...Ví dụ có đơn vị:
var elapsed_ms = (new Date()).getTime() - start_ms;
3. Names That Can’t Be Misconstrued
Tránh tên gây nhầm lẫn.\
Dùng
min_/max_cho giới hạn,first/lastcho phạm vi bao gồm,begin/endcho phạm vi nửa mở.\Boolean nên bắt đầu bằng
is_,has_,can_.\Ví dụ:
# Không rõ nghĩa read_password = True # Rõ ràng hơn need_password = True
4. Aesthetics
Code nên sạch và gọn.\
Quy tắc: layout đồng nhất, code giống nhau nên trông giống nhau, nhóm dòng liên quan.\
Dùng helper method để rút gọn test case.\
Ví dụ:
// Trước assert(ExpandFullName("Doug Adams") == "Mr. Douglas Adams"); assert(ExpandFullName("No Such Guy") == ""); // Sau CheckFullName("Doug Adams", "Mr. Douglas Adams", ""); CheckFullName("No Such Guy", "", "no match found");
5. Knowing What to Comment
Comment nên giải thích tại sao, không lặp lại cái gì.\
Tránh comment hiển nhiên.\
Viết điều giúp người đọc sau này hiểu nhanh hơn.\
Ví dụ:
// Phiên bản nhanh của "hash = (65599 * hash) + c" hash = (hash << 6) + (hash << 16) - hash + c;
6. Making Comments Precise and Compact
Comment phải ngắn gọn, chính xác.\
Tránh dùng đại từ mơ hồ (“it”, “this”).\
Dùng ví dụ input/output, đặc biệt với edge case.\
Ví dụ:
# Cắt chuỗi nếu dài quá max_chars và thêm "..." def Truncate(text, max_chars): ...
7. Making Control Flow Easy to Read
Viết
if/elserõ ràng.\Dùng return sớm để giảm nesting.\
Tránh
gotovàdo/while.\Ví dụ:
# Lồng nhiều tầng if user: if user.is_active: return True else: return False # Return sớm if not user: return False return user.is_active
8. Breaking Down Giant Expressions
Chia nhỏ biểu thức phức tạp.\
Dùng biến trung gian để dễ hiểu hơn.\
Áp dụng luật De Morgan khi cần.\
Ví dụ:
# Khó đọc if not (file_exists and not file_is_empty): # Rõ ràng hơn missing_or_empty = (not file_exists) or file_is_empty if missing_or_empty: ...
9. Variables and Readability
Ít biến hơn → code dễ đọc hơn.\
Thu hẹp phạm vi biến.\
Ưu tiên biến chỉ gán 1 lần.\
Ví dụ:
# Không tốt: tái sử dụng biến result = query_db() result = format(result) # Tốt hơn raw_result = query_db() formatted = format(raw_result)
10. Extracting Unrelated Subproblems
Tách logic không liên quan thành hàm riêng.\
Giúp code tái sử dụng và dễ hiểu hơn.\
Ví dụ:
# Trước def find_closest_location(user, locations): best_dist = float("inf") for loc in locations: dist = compute_distance(user, loc) if dist < best_dist: best_dist = dist best_loc = loc return best_loc# Sau def distance_between(a, b): ... def find_closest_location(user, locations): return min(locations, key=lambda loc: distance_between(user, loc))
11. One Task at a Time
Mỗi hàm chỉ nên làm 1 việc.\
Công việc nhỏ dễ test và dễ maintain.\
Ví dụ:
# Trước: parse + validate chung def get_user_id(data): id = int(data.split(",")[0]) if id < 0: raise ValueError("Invalid id") return id # Sau: tách riêng def parse_id(data): ... def validate_id(id): ...
12. Turning Thoughts into Code
Viết code giống cách mình nghĩ.\
Dùng ngôn ngữ diễn đạt rõ ràng, tận dụng thư viện.\
Ví dụ:
# Ý nghĩ: "lấy email user active" emails = [user.email for user in users if user.is_active]
13. Writing Less Code
Ít code hơn → ít bug hơn.\
Không viết tính năng thừa.\
Tận dụng thư viện và công cụ có sẵn.\
Ví dụ:
# Thay vì viết code tìm file grep "keyword" *.txt
14. Testing and Readability
Test cũng cần dễ đọc và dễ sửa.\
Dùng input có ý nghĩa.\
Đặt tên test mô tả rõ ràng.\
Message lỗi phải rõ ràng.\
Ví dụ:
# Không tốt def test_1(): assert f(123, 5) == 345 # Tốt hơn def test_add_offset_to_id(): assert f(user_id=123, offset=5) == 345
15. Designing and Implementing a “Minute/Hour Counter”
Bài toán ví dụ: đếm sự kiện theo phút/giờ.\
3 cách tiếp cận:
- Naive – đơn giản nhưng không hiệu quả.\
- Conveyor belt design – dịch sự kiện theo thời gian.\
- Time-bucketed design – chia thành bucket cố định.\
Bài học: thiết kế rõ ràng và dễ bảo trì tốt hơn hack nhanh.\
Ví dụ (giản lược):
class MinuteHourCounter: def __init__(self): self.minute_buckets = [0] * 60 self.hour_buckets = [0] * 24 def record_event(self, timestamp): self.minute_buckets[timestamp.minute] += 1 self.hour_buckets[timestamp.hour] += 1