Hướng dẫn độ dài tên biến & hàm - Quy ước đặt tên trong lập trình

9 phút đọc

Trong lập trình, việc đặt tên là một trong những yếu tố quan trọng nhất ảnh hưởng đến khả năng đọc mã nguồn. Tên quá ngắn không truyền đạt được ý nghĩa; tên quá dài khiến mã nguồn trở nên rườm rà. Việc chọn độ dài phù hợp đòi hỏi sự đánh giá dựa trên phạm vi và độ phức tạp. Bài viết này đề cập đến hướng dẫn về độ dài đặt tên và quy ước riêng cho từng ngôn ngữ. Để tìm hiểu thêm, hãy xem sách về thực hành clean code. Kiểm tra độ dài định danh của bạn với Bộ đếm ký tự.

Độ dài tên biến theo phạm vi

Độ dài phù hợp của tên biến tỷ lệ thuận với phạm vi của nó. Nguyên tắc này được ủng hộ rộng rãi trong cuốn "Clean Code" của Robert C. Martin và các hướng dẫn phong cách của Google. Lý do bắt nguồn từ tâm lý học nhận thức: bộ nhớ làm việc của con người chỉ có thể giữ đồng thời 4–7 khối thông tin. Đối với biến có phạm vi rộng, bản thân tên phải khôi phục được ý nghĩa mà không cần ngữ cảnh xung quanh. Ngược lại, trong vòng lặp 2–3 dòng, ngữ cảnh đóng vai trò như một khối thông tin, nên tên ngắn như i giúp giảm tải nhận thức.

Phạm viĐộ dài khuyến nghịVí dụLý do
Bộ đếm vòng lặp (1–3 dòng)1–2 ký tựi, j, kQuy ước được hiểu rộng rãi
Lambda / khối ngắn (≤5 dòng)3–8 ký tựitem, user, valNgữ cảnh làm rõ kiểu/vai trò
Biến cục bộ trong hàm8–15 ký tựuserName, totalPriceVai trò phải rõ ràng trong phạm vi hàm
Trường/thuộc tính của lớp10–20 ký tựmaxRetryCount, isAuthenticatedĐược tham chiếu trong toàn bộ lớp
Biến toàn cục / hằng số15–25 ký tựMAX_CONNECTION_TIMEOUT, DEFAULT_PAGE_SIZEPhải rõ ràng trong toàn bộ mã nguồn

Phân tích độ dài đặt tên của các dự án OSS lớn

Độ dài định danh trong các dự án mã nguồn mở thực tế trông như thế nào? Phân tích mã nguồn từ các dự án lớn cho thấy sự khác biệt rõ ràng về độ dài đặt tên tùy thuộc vào ngôn ngữ và tính chất dự án.

Dự ánNgôn ngữĐộ dài biến TBĐộ dài hàm TBĐặc điểm
Linux KernelC~6 ký tự~12 ký tựBiến ngắn; tên hàm dài hơn do tiền tố module
Spring FrameworkJava~12 ký tự~18 ký tựĐặt tên mô tả kỹ lưỡng; nhìn chung dài
CPythonPython~8 ký tự~14 ký tựBao gồm dấu gạch dưới phân tách từ snake_case
ReactJavaScript~9 ký tự~15 ký tựTên component thường dài; biến nội bộ ngắn
KubernetesGo~7 ký tự~13 ký tựPhản ánh văn hóa ngắn gọn của Go
Ruby on RailsRuby~9 ký tự~15 ký tựTên phương thức kiểu DSL gần với ngôn ngữ tự nhiên

Một mẫu đáng chú ý là các dự án C có tên biến ngắn, nhưng tên hàm bao gồm tiền tố module (tcp_v4_connect, ext4_read_inode) khiến chúng tương đối dài. Trong C, vốn không có namespace, tiền tố đóng vai trò thay thế namespace. Ngược lại, Spring Framework của Java chuẩn hóa tên dài với việc tự động hoàn thành của IDE là điều hiển nhiên — tên lớp vượt quá 50 ký tự như AbstractTransactionalDataSourceSpringContextTests không phải là hiếm.

Hướng dẫn tên hàm và lớp

Loại định danhĐộ dài khuyến nghịNguyên tắc đặt tênVí dụ
Tên hàm10–25 ký tựĐịnh dạng động từ + đối tượngcalculateTotalPrice, sendEmailNotification
Tên lớp10–25 ký tựDanh từ hoặc cụm danh từUserRepository, PaymentProcessor
Tên interface10–25 ký tựTính từ hoặc danh từ mô tả hành viSerializable, EventListener
Tên hằng số10–30 ký tựUPPER_SNAKE_CASE với ý nghĩa cụ thểMAX_RETRY_COUNT, DEFAULT_TIMEOUT_MS
Biến/hàm Boolean10–20 ký tựTiền tố is/has/can/shouldisValid, hasPermission, canExecute

Hàm nên luôn bắt đầu bằng một động từ. fetchData() rõ ràng hơn data(); validateInput() tốt hơn validation().

Quy ước riêng theo ngôn ngữ

Ngôn ngữBiến/HàmLớpHằng sốHướng dẫn phong cách
JavacamelCasePascalCaseUPPER_SNAKE_CASEGoogle Java Style Guide
Pythonsnake_casePascalCaseUPPER_SNAKE_CASEPEP 8
JavaScriptcamelCasePascalCaseUPPER_SNAKE_CASEAirbnb Style Guide
GocamelCase / PascalCasePascalCasePascalCaseEffective Go
Rubysnake_casePascalCaseUPPER_SNAKE_CASERuby Style Guide
C#camelCase / PascalCasePascalCasePascalCaseMicrosoft C# Conventions

IDE Autocomplete và độ dài tên

Mối lo ngại rằng "tên dài gõ mệt" phần lớn đã được loại bỏ bởi các IDE hiện đại. So sánh tính năng tự động hoàn thành giữa các IDE chính cho thấy độ dài tên có tác động tối thiểu đến tốc độ phát triển.

IDE / Trình soạn thảoKích hoạt hoàn thànhChiến lược khớpHỗ trợ tên dài
IntelliJ IDEATự động khi gõKhớp chữ cái đầu CamelCase (gUNgetUserName)2–3 chữ cái đầu thu hẹp ứng viên; tên dài tốn ít công sức
VS CodeTự động khi gõKhớp mờ (usrnmuserName)Hiển thị khớp một phần; không cần gõ chính xác
Vim / Neovim (LSP)Ctrl+N hoặc tích hợp LSPHoàn thành dựa trên LSP nhận biết kiểuHoàn thành tương đương IDE qua coc.nvim hoặc nvim-cmp

Tính năng khớp CamelCase của IntelliJ IDEA đặc biệt mạnh mẽ — chỉ cần gõ ACTDSCT là hoàn thành thành AbstractConcurrentTransactionalDataSourceSpringContextTests. Điều này có nghĩa là độ dài tên không cần bị giới hạn bởi công sức gõ; bạn có thể chọn độ dài tối ưu hoàn toàn vì mục đích dễ đọc.

Thông tin thú vị về đặt tên

Hướng dẫn phong cách mã nguồn Linux kernel ưu tiên tên biến ngắn. Chính Linus Torvalds đã tuyên bố rằng biến vòng lặp nên dùng i thay vì loop_counter. Ngược lại, hướng dẫn phong cách Java của Google không khuyến khích tên một ký tự ngoài bộ đếm vòng lặp và tham số lambda. Sự tương phản này phản ánh các bối cảnh khác nhau: mã kernel được đọc bởi một nhóm nhỏ chuyên gia so với dịch vụ web quy mô lớn được đọc bởi nhiều lập trình viên. Các nghiên cứu về dự án mã nguồn mở trên GitHub cho thấy độ dài trung bình của tên biến là khoảng 8,5 ký tự.

Vấn đề với tên quá dài và quá ngắn

Lỗi đặt tên rơi vào hai thái cực: quá ngắn để truyền đạt ý nghĩa, và quá dài để đọc thoải mái. Những tên ngắn như d, tmp, hoặc val ngoài bộ đếm vòng lặp trở nên khó hiểu chỉ trong vài ngày — ngay cả với chính tác giả.

Tên quá dài cũng gây vấn đề tương tự. Một biến như numberOfItemsInTheShoppingCartBeforeDiscount không vừa trên một dòng và thực sự làm giảm khả năng đọc. Điểm cân bằng lý tưởng là một tên truyền đạt vai trò của nó trong nháy mắt mà không làm gián đoạn luồng mã xung quanh.

Từ góc độ khoa học nhận thức, mối quan hệ giữa độ dài định danh và tốc độ đọc tuân theo đường cong hình chữ U. Tên quá ngắn gây chi phí nhận thức cho "tái tạo ý nghĩa," trong khi tên quá dài gây chi phí cho "quét thị giác." Nghiên cứu cho thấy các định danh tiếng Anh trong khoảng 8–20 ký tự đạt hiệu quả đọc cao nhất. Điều này xuất phát từ sự cân bằng giữa độ dài chuỗi mà thị giác con người có thể nhận diện cùng lúc (~7–10 ký tự) và số từ tối thiểu cần thiết để truyền đạt ý nghĩa (2–3 từ).

Tên biến Unicode và Multibyte

Nhiều ngôn ngữ lập trình hỗ trợ định danh Unicode, nhưng việc sử dụng ký tự không phải ASCII trong tên biến gây ra một số cạm bẫy trên thực tế.

Ngôn ngữBiến UnicodeVí dụLưu ý
Python 3Hỗ trợ đầy đủ名前 = "Taro"PEP 8 khuyến nghị chỉ dùng ASCII; tránh trong nhóm quốc tế
RubyHỗ trợ đầy đủ数値 = 42Cần magic comment # encoding: utf-8 (trước Ruby 2.0)
JavaScriptCho phép Unicode escapelet café = trueChuẩn hóa NFC/NFD có thể khiến tên trông giống nhau nhưng khác nhau
JavaHỗ trợ đầy đủint 金額 = 1000;Biên dịch được, nhưng hầu hết hướng dẫn phong cách không khuyến khích
GoDanh mục Unicode Letter名前 := "Taro"Chỉ cho phép ký tự thuộc danh mục Letter của Unicode
C / C++Hạn chế (C11/C++11+)int données = 0;Hỗ trợ khác nhau tùy trình biên dịch

Vấn đề chuẩn hóa Unicode của JavaScript đáng được chú ý đặc biệt. Tên biến café có thể được biểu diễn theo hai cách: dạng NFC với é là một ký tự đơn (U+00E9), hoặc dạng NFD với e + dấu kết hợp (U+0065 U+0301). Chúng trông giống hệt nhau nhưng được xử lý như các định danh khác nhau. Vì hệ thống tệp của macOS (APFS) sử dụng NFD, các lỗi không mong muốn có thể xảy ra khi tạo tên biến từ tên tệp.

Xung đột từ khóa dành riêng là một trường hợp biên thường bị bỏ qua. Trong Python, class, import, và return là từ khóa dành riêng, nhưng các cách giải quyết như cls (viết tắt của class) và klass đã trở thành quy ước phổ biến. Trong JavaScript, class trở thành từ khóa dành riêng trong ES6, gây ra lỗi cú pháp trong mã trước ES6 sử dụng nó làm tên biến — một vấn đề di chuyển thực tế.

Các lỗi thường gặp

Kỹ thuật đặt tên chuyên nghiệp

Thực thi quy ước đặt tên bằng Linters

Để thống nhất quy ước đặt tên trong nhóm, kiểm tra tự động bằng linter là thiết yếu. Dưới đây là các linter chính và quy tắc liên quan đến đặt tên cho từng ngôn ngữ.

Ngôn ngữLinterQuy tắc đặt tênVí dụ cấu hình
JavaScript / TypeScriptESLint@typescript-eslint/naming-conventionBắt buộc camelCase cho biến, UPPER_CASE cho hằng số, PascalCase cho kiểu
Pythonpylint / RuffC0103 (invalid-name)Bắt buộc snake_case; đặt độ dài tối thiểu (mặc định: 2 ký tự)
JavaCheckstyleMemberName, MethodNameĐịnh nghĩa quy tắc đặt tên qua mẫu regex
Gogolangci-lintrevive's var-namingBắt buộc MixedCaps; thống nhất viết hoa từ viết tắt (ID, URL)
RubyRuboCopNaming/VariableNameBắt buộc snake_case; đặt giới hạn độ dài tối đa

Quy tắc @typescript-eslint/naming-convention của ESLint đặc biệt linh hoạt, cho phép quy tắc đặt tên khác nhau cho từng loại định danh (biến, hàm, lớp, interface, v.v.). Bạn thậm chí có thể bắt buộc các ràng buộc ngữ nghĩa như "biến Boolean phải bắt đầu bằng is, has, hoặc should." Tích hợp linter vào pipeline CI/CD giúp tự động phát hiện vi phạm đặt tên trước khi merge.

Kết luận

Độ dài tên phù hợp tỷ lệ thuận với phạm vi: 1–2 ký tự cho bộ đếm vòng lặp, 8–15 cho biến cục bộ, 15–25 cho hằng số toàn cục. Nguyên tắc này có cơ sở từ khoa học nhận thức — dung lượng bộ nhớ làm việc của con người giới hạn lượng ngữ cảnh mà một tên phải tự mang theo. Phân tích các dự án OSS lớn xác nhận mẫu này, từ trung bình 6 ký tự cho biến của Linux Kernel đến trung bình 12 ký tự của Spring Framework. Mặc dù hỗ trợ tên biến Unicode đang mở rộng, các vấn đề chuẩn hóa và khả năng đọc trong nhóm quốc tế khiến đặt tên chỉ dùng ASCII là lựa chọn thực tế. Tránh viết tắt quá mức và ký pháp Hungary, đồng thời thực thi quy ước đặt tên thông qua linter tích hợp vào pipeline CI/CD. Sử dụng Bộ đếm ký tự để kiểm tra độ dài định danh của bạn.