Clean Code: 10 Rules I Actually Follow (And 5 I Ignore)

March 2026 · 13 min read · 3,203 words · Last Updated: March 31, 2026Advanced

💡 Key Takeaways

  • Rule I Follow #1: Functions Should Do One Thing (But I Define "One Thing" Differently)
  • Rule I Follow #2: Meaningful Names Are Non-Negotiable
  • Rule I Follow #3: Comments Explain Why, Not What
  • Rule I Follow #4: Keep Functions and Classes Small (With Nuance)

Tôi đã nhìn chằm chằm vào mã của người khác được 14 năm nay với vai trò là kiến trúc sư phần mềm cao cấp tại một công ty fintech vừa và nhỏ, và tôi có thể nói với bạn chính xác lúc nào tôi ngừng trở thành một tín đồ của mã sạch: đó là lúc 2:47 sáng vào một thứ Ba vào tháng Ba năm 2019, khi hệ thống xử lý thanh toán của chúng tôi gặp sự cố vì ai đó đã dành ba ngày để tái cấu trúc một mô-đun hoàn toàn hoạt động tốt để tuân theo từng quy tắc trong cuốn sách của Uncle Bob. Sự mỉa mai? Lỗi đã được giới thiệu trong quá trình "dọn dẹp."

💡 Những Điều Chính

  • Quy Tắc Tôi Theo Dõi #1: Các Hàm Nên Thực Hiện Một Việc (Nhưng Tôi Định Nghĩ "Một Việc" Khác)
  • Quy Tắc Tôi Theo Dõi #2: Tên Gọi Có Ý Nghĩa Là Không Thể Thương Lượng
  • Quy Tắc Tôi Theo Dõi #3: Bình Luận Giải Thích Tại Sao, Không Phải Là Gì
  • Quy Tắc Tôi Theo Dõi #4: Giữ Cho Các Hàm và Lớp Nhỏ (Với Sự Nhận Thức)

Tối hôm đó đã thay đổi cách tôi nghĩ về chất lượng mã. Tôi không nói rằng các nguyên tắc mã sạch là sai—xa xôi khỏi điều đó. Nhưng sau khi xem xét hơn 10.000 yêu cầu kéo, hướng dẫn 47 nhà phát triển, và phát hành 23 sản phẩm lớn, tôi đã học được rằng việc tuân thủ một cách mù quáng bất kỳ bộ quy tắc nào chỉ là một hình thức khác của nợ kỹ thuật. Một số quy tắc mã sạch là vàng tuyệt đối. Những cái khác? Chúng phụ thuộc vào ngữ cảnh tốt nhất, và gây hại tích cực nhất tồi tệ nhất.

Dưới đây là những gì tôi thực sự làm trong mã sản xuất, và quan trọng hơn, tại sao tôi làm điều đó.

Quy Tắc Tôi Theo Dõi #1: Các Hàm Nên Thực Hiện Một Việc (Nhưng Tôi Định Nghĩ "Một Việc" Khác)

Nguyên tắc trách nhiệm đơn lẻ cho các hàm có lẽ là quy tắc quý giá nhất mà tôi tuân theo một cách tôn thờ. Nhưng đây là chỗ tôi khác biệt so với sách giáo khoa: Tôi không đo lường "một việc" bằng số dòng mã hay số lượng thao tác. Tôi đo lường nó bằng sự gắn kết khái niệm.

Quý trước, tôi đã xem xét một hàm dài 8 dòng nhưng vi phạm SRP một cách ngoạn mục. Nó xác thực đầu vào của người dùng VÀ ghi lại kết quả xác thực VÀ cập nhật bộ nhớ đệm. Ba trách nhiệm riêng biệt bị nhồi nhét vào 8 dòng. So sánh điều đó với một hàm dài 45 dòng mà tôi đã viết vào tháng trước để điều phối một giao dịch cơ sở dữ liệu phức tạp—nó thực hiện "một việc" (hoàn thành giao dịch thanh toán), nhưng một việc đó yêu cầu nhiều bước cần phải cùng nhau.

Dưới đây là bài kiểm tra litmus của tôi: Tôi có thể mô tả những gì hàm này làm trong một câu mà không sử dụng từ "và" không? Nếu tôi cần nói "hàm này xác thực đầu vào VÀ gửi một email," thì nó đang thực hiện hai việc. Nhưng nếu tôi nói "hàm này xử lý yêu cầu hoàn tiền," và điều đó tự nhiên bao gồm xác thực, cập nhật cơ sở dữ liệu và thông báo—đó vẫn là một việc ở mức độ trừu tượng đúng.

Trên thực tế, điều này có nghĩa là các hàm của tôi trung bình từ 25-30 dòng thay vì 10-15 dòng mà những người thuần túy khuyên dùng. Nhưng tỷ lệ lỗi của chúng tôi trên những hàm này thấp hơn 40% so với mã quá trích xuất mà chúng tôi đã có trước đó. Tại sao? Bởi vì việc giữ các thao tác liên quan cùng nhau giảm tải khối lượng nhận thức để hiểu hệ thống. Khi mọi thứ bị chia nhỏ thành các hàm nhỏ, bạn dành nhiều thời gian hơn để nhảy giữa các tệp thay vì hiểu logic kinh doanh.

Chiến thắng thực sự ở đây là khả năng kiểm tra. Một hàm thực hiện một việc khái niệm là dễ kiểm tra, ngay cả khi nó dài 40 dòng. Bạn mô phỏng các phụ thuộc, gọi hàm, khẳng định kết quả. Xong. Khi bạn đã tách mọi thứ thành các hàm dài 5 dòng, bạn sẽ kết thúc với các bài kiểm tra tích hợp vì kiểm tra đơn vị trở nên vô nghĩa.

Quy Tắc Tôi Theo Dõi #2: Tên Gọi Có Ý Nghĩa Là Không Thể Thương Lượng

Tôi sẽ chết trên đồi này: tên biến và hàm là tài liệu quan trọng nhất mà bạn sẽ viết. Tôi đã từ chối các yêu cầu kéo chỉ vì lý do đặt tên kém, và tôi sẽ làm điều đó một lần nữa.

"Việc tuân thủ mù quáng bất kỳ bộ quy tắc nào chỉ là một hình thức khác của nợ kỹ thuật. Mã tốt nhất không phải là mã sạch nhất—đó là mã có thể phát hành một cách đáng tin cậy và có thể được duy trì bởi nhóm của bạn."

Hai tháng trước, một nhà phát triển mới đã gửi mã với một hàm có tên là `processData()`. Tôi đã gửi lại với một video Loom dài 10 phút giải thích lý do. Hàm đó thật sự xác thực số thẻ thanh toán theo thuật toán Luhn. Tên đúng là `validateCardNumberChecksum()`. Có, nó dài hơn. Có, nó cụ thể hơn. Đó chính xác là mục đích.

Dưới đây là hệ thống đặt tên của tôi, được tinh chỉnh qua hàng ngàn cuộc đánh giá mã:

Tác động là có thể đo lường. Sau khi thực hiện các quy tắc đặt tên nghiêm ngặt trong nhóm của chúng tôi 18 tháng trước, thời gian đánh giá yêu cầu kéo trung bình của chúng tôi giảm từ 3,2 giờ xuống còn 1,8 giờ. Tại sao? Bởi vì các người đánh giá dành ít thời gian hơn để giải mã mã đang làm gì và nhiều thời gian hơn để đánh giá liệu nó có thực hiện đúng hay không.

Tôi cũng áp dụng quy tắc "không viết ngắn gọn" với chính xác ba ngoại lệ: `id`, `url`, và `api`. Mọi thứ khác đều được viết đầy đủ. `usr` trở thành `user`. `btn` trở thành `button`. `calc` trở thành `calculate`. Những phím gõ thêm đó có giá trị khi ai đó đang gỡ lỗi lúc 11 giờ tối và không phải đoán xem `tmpBfr` có nghĩa là gì.

Quy Tắc Tôi Theo Dõi #3: Bình Luận Giải Thích Tại Sao, Không Phải Là Gì

Tôi đã thấy hai cực đoan trong sự nghiệp của mình: các mã nguồn không có bình luận và các mã nguồn mà mỗi dòng đều có bình luận. Cả hai đều sai, nhưng mã có quá nhiều bình luận thực sự tệ hơn vì nó tạo ra gánh nặng bảo trì và thường xuyên nói dối.

Quy Tắc Mã SạchKhi Nào Thực HiệnKhi Nào Bỏ QuaTác Động Thực Tế
Các hàm nên nhỏCác đường dẫn mã có lưu lượng cao, các mô-đun thường xuyên chỉnh sửaLogic điều phối phức tạp, xử lý giao dịchSplitting sớm tạo ra gánh nặng điều hướng
Không có bình luận trong mãLogic kinh doanh tự giải thíchCác thuật toán phức tạp, yêu cầu quy định, tối ưu hóa không rõ ràngThiếu ngữ cảnh tốn hàng giờ trong việc gỡ lỗi
DRY (Don't Repeat Yourself)Logic kinh doanh cốt lõi, các biến đổi dữ liệuMã trông giống nhau nhưng khác biệt theo ngữ cảnhTrừu tượng hóa quá mức tạo ra các phụ thuộc mong manh
Tránh ám ảnh nguyên thủyMô hình miền, ranh giới APICác tiện ích nội bộ đơn giản, các đường dẫn quan trọng về hiệu suấtBọc quá mức tăng tải nhận thức

Quy tắc của tôi rất đơn giản: nếu bạn đang giải thích mã đang làm gì, thì chắc chắn mã đó không tốt. Nếu bạn đang giải thích lý do bạn đã đưa ra quyết định cụ thể nào đó, đó là một bình luận tốt. Dưới đây là một ví dụ thực tế từ o

C

Written by the Cod-AI Team

Our editorial team specializes in software development and programming. We research, test, and write in-depth guides to help you work smarter with the right tools.

Share This Article

Twitter LinkedIn Reddit HN

Related Tools

Glossary — cod-ai.com Changelog — cod-ai.com JSON vs XML: Data Format Comparison

Related Articles

Docker for Developers: The Practical Guide — cod-ai.com 7 REST API Design Mistakes That Will Haunt You Regular Expressions: A Practical Tutorial — cod-ai.com

Put this into practice

Try Our Free Tools →