Nghệ thuật của code "dễ đọc" (Phần 1)
Chào các bạn, hôm nọ mình có đọc được bài http://daynhauhoc.com/t/lam-sao-de-su-dung-bien-hieu-qua-hon-part1/6921 của anh thanhmssl10 và thấy rất hay. Tiện đây mình cũng đang đọc một quyển sách là "The art of readable code" và mình cũng muốn dịch nó để mọi người cùng tham khảo. Mình đang đọc được 50% thôi và áp dụng cũng chưa được nhiều nhưng sau một thời gian áp dụng những tip trong quyển sách này thì mình cũng thấy code của mình cũng phần nào dễ hiểu hơn, thời gian người khác bỏ ra để review code cũng giảm đi đáng kể. Ok bắt đầu thôi.
Chương 1 : Code nên dễ hiểu.
Phần 1 : Điều gì khiến code trở nên "tốt hơn".
Nhiều lập trình viên viết code theo cảm giác và trực giác. Tất cả chúng ta đều biết đoạn code như thế này:
for (Node* node = list->head; node != NULL; node = node->next)
Print(node->data);
luôn tốt hơn đoạn code như thế này:
Node* node = list->head;
if (node == NULL)
return;
while (node->next != NULL) {
Print(node->data);
node = node->next;
}
if (node != NULL)
Print(node->data);
Ngay cả khi hai đoạn code trên đều làm cùng một việc và đều cho ra kết quả như nhau. Nhưng nhiều khi sẽ có những lựa chọn khó khăn hơn. Ví dụ như đoạn code sau:
return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent);
có thể tốt hơn hoặc tệ hơn đoạn code sau:
if (exponent >= 0) {
return mantissa * (1 << exponent);
} else {
return mantissa / (1 << -exponent);
}
Đoạn code thứ nhất trông ngắn gọn hơn, nhưng đoạn code thứ hai trông có vẻ dễ hiểu hơn. Vậy thì code ngắn gọn hay code dễ đọc quan trọng hơn? Nói chung, bạn nên tự đặt ra câu hỏi "Mình sẽ làm thế nào để viết code cho một thứ gì đó?".
Phần 2 : Định lý cơ bản của việc "dễ đọc".
KEY IDEA của phần này là "Code nên viết làm sao để giảm thiểu thời gian người khác bỏ ra để hiểu nó".
Để dễ hiểu hơn cho KEY IDEA mình xin lấy một ví dụ:
Bạn có một người đồng nghiệp và bạn có thể đo được khoảng thời gian người đó bỏ ra để "thực sự hiểu" được đoạn code của bạn có mục đích gì. Khoảng thời gian mà người đó bỏ ra chính là cái mà bạn cần thu nhỏ lại. Khi người đó thực sự hiểu thì anh ta có thể chỉnh sửa, tìm ra bug và biết cách làm thế nào để đoạn code đó tương tác với phần code còn lại.
Và bây giờ có thể bạn sẽ tự đặt ra câu hỏi:
Sao cần phải quan tâm có ai đó có thể hiểu được code của tôi? Tôi là người duy nhất sử dụng đoạn code đó.
Ngay cả khi bạn là người duy nhất trong dự án đó, và dự án đó đáng để bạn theo đuổi. Khi "người nào đó" lại chính là bạn 6 tháng sau đó, khi bạn nhìn vào chính đoạn code của mình và cảm thấy nó chả có tí gì "thân thiện" cả. Và bạn cũng chẳng biết được có ai đó join vào dự án của bạn hay không, hoặc những đoạn code "bỏ đi" ấy có thể được tái sử dụng ở một dự án nào đó. Đó chính là những lý do vì sao bạn nên tìm cách làm giảm thời gian người khác bỏ ra để hiểu được đoạn code đó.
Phần 3 : Ít hơn có luôn là tốt hơn hay không?
Thường thì khi giải quyết một vấn đề, bạn viết càng ít code càng tốt và việc bỏ thời gian đọc 2000 dòng có thể là nhanh hơn là đọc 5000 dòng.
Nhưng ít dòng hơn chưa chắc đã là tốt hơn. Ví dụ đoạn code sau
assert((!(bucket = FindBucket(key))) || !bucket->IsOccupied());
sẽ mất ít thời gian để hiểu hơn nếu nó được chia thành hai dòng như sau:
bucket = FindBucket(key);
if (bucket != NULL) assert(!bucket->IsOccupied());
Tương tự như vậy, một dòng comment cũng có thể giúp bạn hiểu nhanh hơn
// Fast version of "hash = (65599 * hash) + c"
hash = (hash << 6) + (hash << 16) - hash + c;
Do đó, giảm thiểu dòng code là một mục tiêu rất tốt nhưng giảm thiểu thời gian để đọc hiểu được chúng còn tốt hơn.
Phần 4 : Mục tiêu "giảm thời gian hiểu code" có ảnh hưởng gì đến các mục tiêu khác không?
Bạn có thể còn nhiều mục tiêu khác ngoài mục tiêu nói trên như hiệu suất tốt hơn, kiến trúc tốt hơn, test đơn giản hơn,... Nhưng các tác giả đã phát hiện ra rằng mục tiêu "giảm thời gian hiểu code" không ảnh hưởng nhiều đến tất cả các mục tiêu khác. Ngay cả trong mục tiêu "highly optimized code" thì vẫn có cách để làm cho nó vừa tốt và vừa dễ đọc. Và những đoạn code dễ hiểu thường là những đoạn code có kiến trúc tốt và đơn giản trong việc test.
Ok vậy là hết phần thứ nhất của cuốn sách. Mình cũng không giỏi dịch thuật lắm nên nếu mọi người có ý kiến gì đóng góp thì cứ nói nhé mình sẽ sửa ngay khi có thể. Hẹn gặp lại ở phần sau.