15 điểm bởi GN⁺ 2025-07-23 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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

 
GN⁺ 2025-07-23
Ý kiến trên Hacker News
  • Tôi thuộc phe “TODO luôn phải gắn với một issue cụ thể”
    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
    • Theo dõi trong hệ thống bên ngoài không chỉ là tạo issue mà còn kéo theo thêm công sức như phân loại, quản lý backlog, phân loại lại, đóng khi hoàn thành, v.v.
      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
    • Có vẻ tác giả bài viết về cơ bản ủng hộ cách số 3 (chỉ để lại như comment)
      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
    • Người ta nói “chỉ cần bỏ ra 20 giây để ghi lại và quản lý”, nhưng như vậy bản thân nó đã là TODO rồi
      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
    • Nếu việc theo dõi chỉ mất 20 giây thì tốt quá, nhưng ở công ty lớn của tôi, tạo một ticket JIRA phải điền hơn 10 trường bắt buộc
    • Tôi chỉ dùng một quy tắc: mọi TODO đều phải có số ticket đi kèm
      // 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
  • Tôi grep và phân loại như sau
    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 đó
    • Tôi dùng như sau
      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
    • Tôi dùng XXX như một ghi chú cá nhân kiểu “phải sửa trước PR tiếp theo”
      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
    • Tôi thích kiểu này. Ở một dự án, chúng tôi từng cấu hình CI để code có FIXME thì luôn bị reject, còn TODO thì bị reject nếu không có issue ticket
      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
    • Tôi cũng làm tương tự. Với những luồng code còn dang dở nhưng có thể обход, tôi đặt assert thay vì FIXME
      TODO 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
    • Về lý thuyết thì tốt, nhưng tôi nghĩ những quy ước như vậy sẽ vô nghĩa nếu không có công cụ hỗ trợ
      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
  • Làm tôi nhớ đến câu “hoàn hảo là kẻ thù của cái tốt”
    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
    • Với codebase lớn, TODO của nhiều người có thể lẫn vào nhau và trở nên phức tạp, nhưng với dự án cá nhân thì đây là một thỏa hiệp khá tốt
      “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ý
    • Đôi khi tôi để lại TODO vì muốn chừa một tín hiệu trong code rằng còn gì đó cần 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
    • Đã có cả tính năng để máy chủ MCP cho AI tự tạo ticket JIRA và chạy ngay trong Cursor
    • Tôi nghĩ để trong thông điệp commit git sẽ tốt hơn nhiều
      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”
  • Đây là vấn đề về phong cách. Mỗi người có thể có định nghĩa hay văn hóa khác nhau về TODO
    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
  • Tiêu đề có hơi câu click, nhưng tôi hoàn toàn đồng ý với toàn bộ nội dung
    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 ích
    Tô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
    • Đội tôi từng dùng // 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 ra
  • Cần có một chỗ để ghi lại những vấn đề đã biết là có giá trị nhưng không cần phải theo dõi
    Thự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
    • Tôi thực ra chưa từng gặp loại issue như vậy
      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ụ được nêu trong bài

    // TODO: If the user triple-clicks this button, the click handler errors because [xyz]
    Theo tôi, cái này gần với comment thường hơn là TODO thật sự
    Các comment mang tính giải thích như vậy rõ ràng có ích, nhưng gọi là TODO thì hơi gượng
    TODO nên là thứ chỉ ra rõ ràng có một việc thực sự cần làm, tức là báo rằng điều gì đó phải thay đổi, ví dụ như “hàm này phải trả về giá trị khác theo XYZ”
    Theo nghĩa đó, TODO không nên bị chôn trong code mà phải nằm trong issue tracker
    Theo kinh nghiệm của tôi, TODO chỉ là cách biện minh cho việc hy sinh chất lượng code để kịp được duyệt PR. Thực tế nó gần như chẳng bao giờ được làm, chỉ để lại suy nghĩ kiểu “rồi sẽ có dev đàn em nhiều thời gian hơn xử lý sau”

    • Comment là để giải thích vì sao đoạn code này lại hoạt động theo cách đó
      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
    • Tôi không nghĩ ví dụ trên là một comment TODO tích cực cho lắm
      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
    • Có thể xem nó như kiểu “bỏ qua” thôi. Nhiều trường hợp thậm chí không làm cũng không sao
      Đ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
    • Ví dụ đó đúng ra gần với FIXME hơn là TODO
      Nó rõ ràng là lỗi, chỉ là mức cần xử lý không quá cao
  • Tôi phản đối mạnh
    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
  • Tôi cũng dùng theo tầng nghĩa
    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
  • Tôi xem comment là bằng chứng cho thấy khả năng viết code chưa đủ tốt
    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