[Code sao cho chuẩn] – Phần 2: Đặt tên biến – việc đơn giản nhưng bạn đã làm đúng?
clean code
10
readable code
4
White

Tấn Tài Vũ viết ngày 06/10/2017

Không quá khi nói rằng: đặt tên biến là một trong những việc làm mất thời gian nhất khi viết code. Vậy làm thế nào để cải thiện việc này? Chúng ta nên đặt tên biến như thế nào cho phù hợp?

Bạn đã từng trải qua việc vò đầu bứt tóc suy nghĩ cả buổi vẫn không tìm ra 1 cái tên hợp lí cho 1 cái biến vớ vẩn nào đó – khi mà bạn đã đặt 10 cái tên biến khác trong phạm vi đó, hay bạn đã trải qua việc mất cả ngày trời để debug những lỗi tưởng chừng bự như con voi trong khi nó đơn giản chỉ là việc dùng sai hàm, bởi bạn đã nhầm lẫn nội dung xử lí của nó với cái tên chẳng mấy ăn nhập. Vậy mới thấy tên biến đôi khi ảnh hưởng nhiều tới việc viết code như thế nào.

Cũng giống như việc đặt tên các đối tượng khác trong đời sống hằng ngày, tên không được quá phức tạp và dài để khiến nó trở nên khó nhớ, nhưng cũng không được quá đơn giản để khiến nó trở nên mơ hồ và không còn giữ được tính dễ nhận biết. Để làm được điều này, chúng ta nên dựa vào 2 tiêu chí sau đây:

  • Tiêu chí thứ nhất: Tên phải thể hiện được ý nghĩa và vai trò của nó.
  • Tiêu chí thứ hai: Tên phải rõ ràng và tránh bị hiểu lầm.

Như mình đã nói, tiêu chí code sao cho dễ hiểu đóng vai trò rất quan trọng. Do vậy chúng ta sẽ dựa trên 2 tiêu chí này để phân tích và đưa ra những quy tắc đặt tên tối ưu và dễ hiểu nhất.

I. Tên phải thể hiện được ý nghĩa và vai trò của nó

alt text
(Tên phải thể hiện được nhiệm vụ của nó. Nguồn ảnh: Sách The art of readable code)

Có lẽ ai trong chúng ta đều hiểu được tiêu chí này, và rằng cái tên mà chúng ta sẽ đặt cho biến phải thể hiện được ý nghĩa và nhiệm vụ của biến. Vậy hãy lưu ý tới những tiêu chí sau đây:

1. Tránh dùng những từ nhiều nghĩa, hãy dùng những từ có nghĩa cụ thể

Có những từ mà bản thân nó hàm chứa ý nghĩa không rõ ràng; kiểu như “do”, “prepare”, “get” ..v.v. Nếu chúng ta đặt tên hàm kiểu như prepareLayout() hoặc getLayout() thì rất khó để truyền tải được ý nghĩa thật sự của nó là gì.

Giả sử bạn muốn tải một layout từ internet về để xử lí, thì tốt hơn là bạn nên đặt tên kiểu như downloadLayout(), nếu muốn xoá trắng layout trước khi xử lí thì cái tên clearLayout() sẽ hợp lí hơn nhiều.

Một ví dụ khác, giả sử bạn khai báo một lớp xử lí như sau:

class BalanceTree{
    int size;
    …
}

Vậy bạn muốn truyền tải gì qua biến size? Nếu bạn muốn nói về độ cao của cây, hãy dùng từ height, nếu muốn nói tới số lượng nodes thì hãy dùng numNode … Tóm lại là bạn nên tránh dùng những từ có ý nghĩa chung chung mà thay vào đó là dùng những từ có nghĩa cụ thể. Điểm lưu ý tiếp theo là:

2. Chỉ rõ hành vi chứ không phải ý định

Giả sử bạn viết một hàm nhận tham số đầu vào để điều khiển việc có xuất log vào file hay không, và bạn đặt tên cho tham số đó là debug. Bạn quy định nếu debug = TRUE thì xuất log, ngược lại thì không:

function processABC(int param1, int param2, bool debug) {
   . . .
   if(debug) {
      //export log to file
   }
}

Thoạt nhìn thì có vẻ như mọi thứ đều ổn, cho tới khi một người khác tiếp nhận code của bạn. Liệu họ sẽ đủ thời gian để hiểu được debug thực sự là làm gì? Là ghi log, là kích hoạt tham số ẩn hay đơn giản là dừng chương trình khi có bất kì warning nào xảy ra?

Nếu mục tiêu của bạn đơn giản là muốn ghi log, chẳng phải tên biến exportLog rõ ràng hơn nhiều so với debug hay sao? Bạn sẽ tránh được nhiều lỗi và tiết kiệm nhiều thời gian cho người khác chỉ với một thay đổi rất nhỏ này.

3. Chèn thêm những thông tin quan trọng vào tên biến

Đôi khi thể hiện được mục đích của biến thôi là chưa đủ, chúng ta còn cần có những ràng buộc thêm cho biến. Với những tình huống này, chúng ta nên đính kèm những ràng buộc này vào tên của chúng.

Ví dụ, liên quan tới kiểu dữ liệu của biến. Giả sử chúng ta có đoạn mã xử lí để tính khoảng thời gian như sau:

var start = (new Date()).getTime();
var elapsed = (new Date()).getTime() - start;

WriteToScreen( “The processing time is: ” + elapsed + “seconds”);

Có điều gì không đúng ở đây không?

Câu trả lời nằm ở chỗ hàm getTimet() trả về đơn vị là mili giây trong khi ta đang muốn xuất ra thông tin ở đơn vị giây. Đôi khi đơn vị tính của giá trị đóng vai trò quan trọng trong các xử lí của chúng ta, có thể người lập trình hiểu rõ được giá trị trả về của hàm getTime() là mili giây, tuy nhiên có thể vì vội vàng xử lí hay điều gì đó mà họ quên mất điều này ở kết quả tính cuối cùng.

Chúng ta có thể tránh được những sai sót này đơn giản chỉ bằng việc chỉ rõ đơn vị tính của biến. Chúng ta sẽ dùng start_ms thay cho start, dùng elapsed_ms thay cho elapsed. Như vậy code sẽ tường minh và rõ ràng hơn:

var start_ms = (new Date()).getTime();
var elapsed_ms = (new Date()).getTime() - start_ms;

WriteToScreen( “The processing time is: ” + elapsed_ms / 1000 + “seconds”);

Tương tự với ý tưởng trên, những trường hợp mà chúng ta cũng nên thể hiện ở tên biến như: trạng thái, phạm vi truy cập, …

4. Biến tạm - hãy đặt tên rõ ràng

Có một vấn đề mà chúng ta rất hay gặp phải đó là: đặt tên biến tạm. Hãy thử xem xét các biến tạm hay dùng trong vòng lặp như sau:

for (int i = 0; i < clubs.size(); i++)
    for (int j = 0; j < clubs[i].members.size(); j++)
        for (int k = 0; k < users.size(); k++)
            if (clubs[i].members[k] == users[j])
                cout << "user[" << j << "] is in club[" << i << "]" << endl;

Hầu hết mọi người đều dùng các tên đơn giản như i, j hoặc k để đặt tên biến lặp, điều này không có gì sai cả, tuy nhiên khi có nhiều vòng lặp xử lí cùng 1 lúc, thì có vẻ mọi việc dần trở nên mất kiểm soát. Developer sẽ rất khó để phát hiện các lỗi liên quan tới chỉ số của biến lặp. Do vậy, sẽ tốt hơn nếu ta đính kèm thêm thông tin vào biến lặp để nó rõ nghĩa hơn:

//Dòng code chưa tốt
if (clubs[i].members[k] == users[j])

//Có thể sửa lại như sau:
if (clubs[club_i].members[mem_k] == users[user_j])

//Hoặc sửa thành
if (clubs[ci].members[mk] == users[uj])

Chỉ với thao tác đơn giản là chỉnh sửa tên của biến, chúng ta đã truyền tải rõ hơn ý định logic của mình tới những người phát triển khác. Một việc nhỏ mà lợi ích không hề nhỏ phải không nào?

II. Tên phải rõ ràng và tránh bị hiểu lầm.

alt text
(Cắt bên nào? Nguồn ảnh: The art of readable code)

Với những tiêu chí được đề cập ở trên, chúng ta đã có thêm rất nhiều thông tin vào tên biến, làm cho chúng trở nên dễ hiểu hơn. Ở phần này chúng ta sẽ nói về khía cạnh khác: cần tránh các trường hợp người đọc hiểu lầm ý nghĩa của chúng.

Trong một vài tình huống, việc người đọc code hiểu sai ý của người viết code không phải vì bản thân cái tên biến khó hiểu hay mơ hồ, mà đơn giản chỉ vì người đọc đã có những hình dung khác trước khi họ đọc code. Lấy ví dụ:

class Student{
    String name;
    int subjects_score[];

    //Compute and return the student’s avarage score.
    int getAverageScore(){
         // Iterate through array subjects_score and return (total score / num_subjects)
    }
}

Đoạn code trên đáp ứng tốt các tiêu chí mà chúng ta đã đưa ra ở phần trên, thế nhưng nó sẽ gặp phải một vấn đề: Hầu hết các lập trình viên đều dùng từ get để đặt tên cho hàm có hành động lấy và trả về một thuộc tính nội tại của lớp, chỉ đơn giản là lấy ra mà không phải tốn chi phí tính toán. Việc chúng ta dùng từ get đặt tên cho một hàm có xử lí tính toán dường như đi ngược lại với thói quen của những developer khác, nếu người khác tái sử dụng lại hàm tính điểm trung bình này, rất có thể họ sẽ dùng nó theo một cách có thể ảnh hưởng tới hiệu năng của chương trình, làm chương trình chạy chậm hơn.

Mặc dù không vi phạm quy tắc gì đi nữa thì chúng ta cũng nên tránh điều này. Sẽ tốt hơn nếu chúng ta dùng computeAvarageScore() thay cho getAvarageScore(), chúng ta sẽ chỉ nên dùng get để đặt tên cho một hàm không cần tính toán, ví dụ như getStudentName().

Bằng cách thay đổi tên hàm như trên, chúng ta sẽ giúp các lập trình viên khác hiểu chính xác hơn và tránh được các lỗi hiệu suất (performance) tiềm năng có thể xảy ra.

Chốt: Tóm lại thì chúng ta nên đặt tên biến như thế nào?

Tổng kết lại, việc đặt tên biến tưởng chừng đơn giản nhưng chúng ta cũng cần để ý những vấn đề tiềm ẩn có thể xảy ra trong tương lai, các tiêu chí cần nhớ để đặt tên biến có thể được tóm gọn lại như sau:

  • Tiêu chí 1: Tên phải thể hiện được đầy đủ ý nghĩa và vai trò của nó.
    • Tránh dùng từ nhiều nghĩa, hãy dùng những từ có nghĩa cụ thể.
    • Chỉ rõ hành vi thay vì ý định.
    • Chèn thêm những thông tin quan trọng vào tên.
  • Tiêu chí 2: Tên phải rõ ràng và tránh bị hiểu lầm.

Chỉ thế thôi. Chúc vui & enjoy coding!

Bài viết có tham khảo sách Clean code và sách The art of readable code
Bài viết gốc: [Code sao cho chuẩn] – Phần 2: Đặt tên biến – việc đơn giản nhưng bạn đã làm đúng?

vcttai 06-10-2017

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Tấn Tài Vũ

11 bài viết.
91 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
28 6
Nguồn: (Link) Nhắc lại về các kiểu dữ liệu trong Javascript, ta có 5 kiểu dữ liệu cơ bản và 1 kiểu dữ liệu phức hợp. 5 kiểu dữ liệu cơ bản bao gồm...
Tấn Tài Vũ viết 1 năm trước
28 6
White
25 9
Note: Bài viết nguồn ở đây: (Link) Con trỏ this có lẽ là một khái niệm không mấy xa lạ trong lập trình hướng đối tượng, nó là một thể hiện cho đố...
Tấn Tài Vũ viết 1 năm trước
25 9
White
23 1
Mấy hôm nay có dịp ôn lại về HTTPS, mặc dù đã có nhiều tài liệu nói về giao thức này nhưng hầu hết chúng thường được mô tả bằng ngôn ngữ kĩ thuật t...
Tấn Tài Vũ viết 3 tháng trước
23 1
Bài viết liên quan
White
14 0
Có nên viết comment code hay không có lẽ là một trong những vấn đề gây tranh cãi dai dẳng nhất trong giới lập trình. Thuở còn đi học, mình hay ngh...
Tấn Tài Vũ viết 9 tháng trước
14 0
White
5 0
Với những ai đã từng viết code, ngoài việc đảm bảo output đúng, chúng ta cũng thường đặt câu hỏi: “viết code thế này đã chuẩn chưa?” Hầu hết mọi n...
Tấn Tài Vũ viết 10 tháng trước
5 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
11 bài viết.
91 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!