TODO thực ra không phải để 'xử lý'
(sophiebits.com)- Một số nhóm áp dụng chính sách đưa mọi chú thích TODO vào bug tracker hoặc tự động xóa TODO đã tồn tại hơn 1 năm, nhưng không khuyến khích cách làm này
- Chú thích TODO không nhất thiết phải là thứ chỉ có giá trị khi được hoàn thành, mà đóng vai trò như một ảnh chụp nhanh của bộ não, lưu lại bối cảnh và ý tưởng tại thời điểm viết mã
- Những TODO quan trọng nên được quản lý như issue, nhưng phần lớn chỉ là ghi chú về các trường hợp biên hoặc việc có mức ưu tiên thấp
- Một TODO được đặt đúng chỗ sẽ cung cấp gợi ý giúp hiểu được ý định của tác giả lúc đó khi người đọc mã trong tương lai băn khoăn: "Có nên refactor phần này không?"
- Giá trị của TODO nằm ở việc ghi lại bối cảnh, ý định và khả năng, chứ không phải ở việc có hoàn thành hay không, từ đó hỗ trợ bảo trì và cộng tác trong tương lai
Chú thích TODO, có nhất thiết phải xử lý không?
- Một số tổ chức áp dụng quy tắc đưa mọi TODO trong mã vào bug tracker hoặc tự động xóa sau một khoảng thời gian nhất định (hơn 1 năm)
- Tuy nhiên cách tiếp cận này thực tế không hiệu quả và bỏ lỡ bản chất của TODO — nó không chỉ có giá trị khi thực sự được xử lý
Giá trị thực sự của TODO
-
Ví dụ,
// TODO: 다음 주 출시 전에 이 파일의 뒷부분을 완성해야 함kiểu chú thích như vậy có thể thực sự cần được theo dõi
-
Nhưng TODO tốt thường là dạng
// TODO: 사용자가 이 버튼을 트리플 클릭할 경우, 핸들러에서 \[xyz] 오류 발생tức dùng để ghi lại các trường hợp biên, hoặc ý tưởng cải thiện cấu trúc chưa thể làm ngay, những tình huống bị bỏ sót, kèm theo bối cảnh
TODO không phải là 'kế hoạch' mà là 'kênh truyền đạt'
- Phần lớn TODO thực ra có mức ưu tiên thấp và không cần xử lý ngay
- Chúng có vai trò truyền lại suy nghĩ, phán đoán và ngữ cảnh của tác giả tại thời điểm viết cho người đọc mã trong tương lai
- Khi ai đó đọc mã sau này tự hỏi "Có nên thay đổi cấu trúc ở đây không?", TODO sẽ giúp họ hiểu được ý định của tác giả khi đó
Tác dụng của TODO được viết tốt
- TODO trong mã đôi khi cung cấp những gợi ý quan trọng như khả năng có vấn đề, tiềm năng cải thiện cấu trúc, các trường hợp biên chưa được xử lý
- Dù không nhất thiết là một kế hoạch để giải quyết, chúng vẫn đóng vai trò lớn trong việc truyền đạt ngữ cảnh tinh tế cho cộng tác và bảo trì
- Cuối cùng, chú thích TODO là một dạng ghi chép quý giá giúp nâng cao mức độ dễ hiểu của mã và khả năng bảo trì về sau
Kết luận
- TODO không chỉ có giá trị khi được hoàn thành, mà là kênh giao tiếp lưu lại suy nghĩ, ý định và ngữ cảnh của tác giả cho người đọc mã trong tương lai
1 bình luận
Ý kiến trên Hacker News
Tôi nghĩ có ba cách xử lý TODO trước khi merge
1. Để lại issue — nếu đó thật sự là việc cần làm thì nên bỏ ra khoảng 20 giây để ghi lại và theo dõi
2. Làm luôn ngay — nếu việc đó quá nhỏ để tạo issue thì hãy xử lý trước khi commit
3. Đổi thành comment — nếu không đáng sửa, cũng không cần theo dõi nhưng vẫn muốn ghi nhớ thì nên để lại như một comment mã nguồn thông thường
Nếu nghĩ cho sức khỏe thì cũng như ăn bông cải xanh, việc có thói quen theo dõi TODO là điều tốt
Các issue được đăng trong hệ thống bên ngoài có thể không dễ thấy với những lập trình viên đang sửa phần code đó
Nếu thấy chi phí theo dõi cả những thứ có thể sửa rất nhanh là quá tốn kém, thì để lại dưới dạng TODO sẽ hiệu quả hơn
TODO trong code hiện ra ngay khi làm việc với phần code đó, và cũng dễ xóa khi refactor
Nhưng tôi thấy tiếc vì bài đó không nói rõ sự khác nhau giữa comment TODO và comment thường
Chính từ TODO đã có sức nặng thị giác nên có thể nhận ra ngay đó là loại comment gì
Việc cho rằng không nhất thiết phải hiểu TODO đúng theo nghĩa “việc cần làm” có phần hơi đáng ngờ
Tôi nhìn chung đồng ý với ý kiến trong bài, nhưng vẫn thấy cải thiện tốt hơn là cứ để nó thành comment thường
Nếu đưa lên hệ thống ticket thì không chỉ mất hơn 20 giây mà còn dễ gây xao nhãng hơn là hữu ích
// TODO: improve the routing https://jira.com/whatever/TIX-1234
Lý do là nếu comment bị mồ côi thì không ai còn biết tại sao nó được để lại
Nếu chỉ để lại comment trống không, sau này ai đó sẽ quên mục đích và bối cảnh của nó
Vì vậy theo tôi либо phải tạo ticket, либо xử lý ngay
FIXME: phần rõ ràng là sai hoặc bị hỏng, ưu tiên cao nhất
XXX: phần xấu xí hoặc có giả định sai, ưu tiên cao
TODO: phần mà đến lúc nào đó cần triển khai một cách tiếp cận/danh mục/nhánh hoàn toàn mới
NOTE: dùng để truyền đạt thông tin quan trọng hơn comment thông thường
Tôi chủ yếu làm trên các engine code legacy/không được bảo trì, ở đó “code là chân lý”, nên không tạo JIRA mà đọc đến đâu sửa luôn đến đó
TODO: việc bắt buộc phải có trước khi release, hạng mục thiết yếu. Nếu không thuộc loại này thì phải chuyển sang danh mục khác. Đây là thứ chặn release
FUTURE: có thể một ngày nào đó sẽ thành TODO, thường là các yếu tố tùy chọn như thiết kế kiến trúc
MAYDO: có thì tốt, không có cũng được
PERF: làm khi cần thêm hiệu năng
Và tôi cũng dùng các tag mang ý nghĩa theo domain
Theo tôi, TODO không phải code smell mà là thứ tự nhiên tích tụ ở những phần cốt lõi của codebase
Nếu muốn nghiêm túc thì tôi cấu hình CI để reject code có chứa chuỗi đó
Theo nghĩa đó, XXX với tôi lại là ưu tiên cao nhất
Nếu xếp ưu tiên từ trên xuống dưới thì
FIXME: để giữ tập trung. Phải giải quyết xong thì code mới được merge hoặc xem là hoàn chỉnh
XXX: phải sửa sớm. Hiện tại vẫn chạy được nhưng cần sửa nhanh
TODO: cần quay lại sau. Code vẫn hoàn toàn dùng được. Ưu tiên thấp hơn XXX
NOTE: giải thích điểm lạ hoặc điều cần biết để giúp người làm sau
assertthay vì FIXMETODO dùng để để lại các việc khả thi như cải thiện refactor/hiệu năng/độ rõ ràng
NOTE thì tôi dùng để lưu lại thông tin cũ hoặc mạch suy nghĩ khó nhận ra nếu chỉ nhìn vào hiện tại
Càng đúng hơn nếu giả định là đang làm việc theo nhóm
Nhưng điều đó không có nghĩa là bản thân ý tưởng này vô nghĩa — tôi nghĩ những công cụ như vậy nên tồn tại hoặc cần được tạo ra
Những khoản nợ kỹ thuật hay code smell kiểu này đúng ra nên được theo dõi/ghi chép/giải thích tốt hơn, nhưng nếu bắt mọi người làm việc làm giảm năng suất như JIRA thì rốt cuộc họ lại chẳng ghi gì cả
Ít nhất nếu có TODO trong code thì nó vẫn còn được lưu lại ở đâu đó
TODO cũng là một “việc cần làm” thực sự nên nó vẫn có ý nghĩa
“Tôi biết có thể làm tốt hơn, nhưng sẽ không cố tình dừng luồng làm việc của mình chỉ vì điều đó. Tính năng không hỏng, chỉ là có thể tốt hơn nếu làm thêm.”
Việc editor thỉnh thoảng highlight TODO giúp ích khi bạn muốn tranh thủ sửa nhanh một chút
Nhưng phần lớn TODO sẽ nằm đó mãi, hoặc trên thực tế hầu như không bao giờ được xử lý
Dù có đăng lên JIRA, GH Issues, v.v. thì cuối cùng các ghi chép đó vẫn cần được liên kết với nhau
Và nếu chỉ để lại một tham chiếu thì sau này nó có thể mất ý nghĩa, nên trong comment vẫn nên có giải thích đi kèm
Nhiều commit trên thực tế không truyền đạt được nội dung cho tốt
Tôi muốn khuyến khích dùng công cụ tốt hơn thay vì để lại TODO theo kiểu cũ
Nhiều lập trình viên commit quá thưa, rồi nhồi nhiều việc vào một lần
Thông điệp commit cũng thường bị viết vô nghĩa kiểu như “updating somefile.py”
Trong codebase của tôi, TODO được dùng đúng như mô tả ở đây
TODO dùng để mô tả việc triển khai, nhất là ghi lại phần còn thiếu — không nhất thiết mang nghĩa phải xử lý
Theo tôi, để một danh sách việc cần làm thực sự trong chính code thì không có nhiều ý nghĩa. Ưu tiên luôn thay đổi, nên thứ từng quan trọng lúc ghi lại có thể không còn như vậy nữa, và những vấn đề chưa nghĩ tới lại có thể thành việc phải giải quyết sau
Không thể cứ mở PR liên tục chỉ để cập nhật comment TODO
Nếu muốn ghi việc phải làm thì nên quản lý ở bên ngoài như issue tracker, hoặc một tài liệu văn bản dễ cập nhật
Ngay lúc này tôi cũng vừa để lại
#TODOđể ghi chú một tình huống ngoại lệ cực hiếm. Hai năm rồi nó chưa từng thực sự xảy ra, nhưng sau này nếu tôi thắc mắc vì sao mình không xử lý đoạn đó thì nó sẽ hữu íchTôi cũng hiểu ý những người nói rằng những thứ như vậy đôi khi nên chỉ là comment thường. Điều đó phụ thuộc vào tính chất codebase, và trong môi trường như nhóm 2 người của tôi thì cách dùng TODO lại rất hợp
// TBD: [...]cho mục đích kiểu này. Đó là mẹo để những người ám ảnh chuyện TODO không nhận raThực ra không có kế hoạch sửa, nhưng về sau khi có thời gian rảnh có thể sẽ tò mò muốn dọn dẹp, nên vẫn là thứ đáng để ctrl-F tìm lại một lần
Tôi thấy thật vô lý khi quá nhiều công cụ hay quy trình xem TODO là code smell
Theo tôi, đó chỉ là vấn đề ưu tiên, và rốt cuộc vẫn là cửa sổ vỡ (phép ẩn dụ nổi tiếng trong Pragmatic Programmer)
Nếu thật sự đã quyết định sẽ không sửa, thì ghi vào tài liệu phần mềm sẽ tốt hơn
Ví dụ, nếu chỉ viết đơn giản
// If the user triple-clicks this button, the click handler errors because [xyz]
thì sẽ không rõ đó là bug hay là hành vi được chủ ý
TODO là một tín hiệu ngắn gọn rằng “ở đây có phần chưa hoàn hảo, hãy lưu ý khi làm việc”
Nếu đó là việc bắt buộc phải giải quyết thì đúng là nên theo dõi ở nơi khác
Nhưng nếu cố giảm TODO đi thì theo tôi kết quả chỉ là có thêm code không được tài liệu hóa
Có thời gian viết như vậy thì cứ sửa bug luôn, hoặc để lại comment kiểu “triple click bị bỏ qua vì [xyz]” là được
Nếu đã tìm ra cả trigger lẫn nguyên nhân thì tôi nghĩ là 80% công việc đã xong rồi
Điều đáng lo là khi code thực ra không hoạt động hoàn hảo mà ta lại giả định như thể nó có
TODO tốt nhất tôi từng thấy là kiểu “TODO: encrypt this” trong code bảo mật, vì nó ghi rõ là chỗ này chưa mã hóa
Nhờ vậy ai cũng nhanh chóng nhận ra dữ liệu chưa được mã hóa, đồng thời bớt lo là phải chăng việc mã hóa đã được xử lý riêng ở module khác hay sẽ bị mã hóa hai lần
Nó rõ ràng là lỗi, chỉ là mức cần xử lý không quá cao
Hoặc đăng nó thành bug, hoặc nếu không thực sự định làm thì đừng để TODO
// TODO: If the user triple-clicks this button, the click handler errors because [xyz]
Đây chỉ là ghi lại hiện tượng. Bỏ chữ TODO đi mới đúng
FIXME dùng khi chắc chắn phải sửa, hoặc khi bước tiếp theo hiện ra rất rõ
TODO thì dành cho những ý tưởng còn mơ hồ hơn, hoặc đơn giản là để lấy nó ra khỏi đầu rồi tập trung vào việc tiếp theo
Có nhiều tình huống như ý tưởng chưa chín, chưa chắc là nhất định phải làm, hoặc đang chờ thứ gì đó liên quan
Nếu không ghi lại thì nó cứ lởn vởn trong đầu gây rối, còn chỉ cần viết xuống dưới dạng TODO hay gì đó thì tâm lý nhẹ hẳn
Giá mà có thể viết code dễ hiểu ngay mà không cần comment thì tốt
Dù vậy, nếu ngay cả sau này chính tôi đọc lại mà vẫn thấy rối đến mức không hiểu thì đành phải viết comment
Điều buồn là nếu ai đó về sau sửa code mà không cập nhật comment thì nó lại càng gây nhầm lẫn hơn
Theo tôi, TODO không nên tồn tại trong code đã commit, mà phải được quản lý trong hệ thống quản lý dự án hoặc issue mới đúng