Code Ngắn Có Tốt Như Mọi Người Vẫn Tưởng?

Code Ngắn Có Tốt Như Mọi Người Vẫn Tưởng?

"Ai cũng biết debug còn khó gấp đôi việc viết ra chương trình đó. Thế nên nếu bạn cứ cố gắng viết code thông minh hết mức có thể, thì bạn định debug nó thế nào?" - Brian Wilson Kernighan - người đóng góp vào sự phát triển của Unix, đồng tác giả của ngôn ngữ lập trình AWK và AMPL đặt ra câu hỏi.

Ở trường học, chúng ta được dạy rằng viết code càng ngắn càng tốt, ai viết càng gọn gàng là càng "siêu". Và tới khi đi làm, không ít lập trình viên liên tục "thể hiện" sự siêu sao đó của mình trong từng dòng code. Điều đó có thể đúng trong một vài trường hợp, nhưng không phải là tất cả, nhất là khi sự rút gọn đó chỉ nhắm mục đích "show-off" - điều thường thấy ở các lập trình viên mới ra trường.

Lấy một ví dụ đơn giản như thế này:
Code 1:

return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent);

Code 2:

if (exponent >= 0) {
return mantissa * (1 << exponent);
} else {
return mantissa / (1 << -exponent);
}

Theo bạn, code nào "tốt" hơn?
Code 1 rõ ràng ngắn hơn, nhưng Code 2 lại dễ hiểu hơn rất nhiều.

Nếu bạn đang viết code một mình, chạy dự án một mình, duy trì một mình, thì việc bạn viết code ngắn tới đâu cũng không quan trọng nữa, vì khi đó chỉ cần một mình bạn hiểu là đủ. Nhưng hãy đảm bảo rằng không xảy ra tình trạng một ngày đẹp trời nào đó, bạn nhìn vào những dòng code của chính mình và tự hỏi: "Mình viết cái quái gì đây nhỉ?"

Còn một khi đã tham gia vào một team, bạn không chỉ còn tự code tự hiểu nữa, mà bạn cần code để cả team có thể làm được. Code tốt hay không không được đo bằng sự ngắn dài, mà đo bởi sự dễ hiểu - dễ triển khai và dễ sửa chữa. Code càng khó hiểu, team càng khó làm, và hiệu suất công việc chung lại càng giảm xuống.

Hãy nghĩ rộng ra về vấn đề quy mô chung của cả công ty, một dòng code "chỉ mình bạn hiểu" sẽ khiến:

  •  Người khác khó làm được, để đảm bảo tiến độ dự án buộc bạn phải tiếp tục nhiệm vụ đó thay vì có thời gian tiếp cận những thứ thú vị hơn, làm mất thời gian của chính bạn và đồng nghiệp.
  • Khó để cập nhật cho bất kỳ tính năng quay vòng nhanh nào. Bất kỳ thay đổi đòi hỏi thử nghiệm nhiều hơn đáng kể, từ đó làm ảnh hưởng tới chi phí chung của team

Đó chính là sự lãng phí tài nguyên của chính bạn và công ty. Viết 1 dòng code ngắn cũng mất rất nhiều thời gian, vậy nên bạn cần nhớ rằng, mình được trả tiền không phải để thể hiện, bạn được trả tiền để mang lại lợi ích cho công ty và trở thành một phần trong cộng đồng đó.

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;

Vậy, khi nào bạn cần viết những dòng code ngắn gọn?

Đó là khi bạn viết:

  • Mã giao thức
  • Hướng dẫn đồ họa (GPU)
  • Tối ưu thời gian cho những tình huống cụ thể
  • ARM-C khi bạn có bộ nhớ cache hạn chế
  • CPLD với lưu trữ flash hạn chế
  • Trình điều khiển chương trình cơ sở, lưu trữ hạn chế
    ...

Trừ khi bạn có môi trường xử lý rất hạn chế, nếu không thì thật lãng phí thời gian của mọi người chỉ để cố gắng viết code thật ngắn, thử và tối ưu hóa 396ns (nano giây). Công nghệ ngày nay thật sự rất thông minh, và việc cố gắng viết code "1 dòng" chỉ khiến bạn càng tốn công sức hơn, bởi rõ ràng để code và thu gọn code không phải là một quá trình "phút mốt" là xong. Chẳng có lý do gì để đánh dối thời gian, công sức và cả tiền bạc của bản thân, đồng nghiệp và công ty cho những việc như vậy.

Mặc dù code ngắn gọn là một mục tiêu nên hướng tới, nhưng 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 "tốt" là những đoạn code có kiến trúc tốt và đơn giản trong việc test thay vì chỉ "ngắn".

Đừng để những yếu tố bên ngoài bóp chết giá trị thật sự của việc lập trình. Chúc các bạn làm tốt!