TODO ไม่ได้มีไว้เพื่อ “ทำให้เสร็จ” เสมอไป
(sophiebits.com)- บางทีมใช้แนวทางให้ลงทะเบียน คอมเมนต์ TODO ทุกอันไว้ใน bug tracker หรือให้ลบ TODO ที่มีอายุมากกว่า 1 ปีโดยอัตโนมัติ แต่แนวปฏิบัติเหล่านี้ ไม่แนะนำ
- คอมเมนต์ TODO ไม่ได้มีคุณค่าเฉพาะเมื่อเป็นสิ่งที่ ต้องทำให้เสร็จเท่านั้น แต่ทำหน้าที่เป็น ภาพสแนปช็อตของสมอง ที่บันทึกบริบทและไอเดีย ณ ตอนเขียนโค้ด
- TODO ที่สำคัญควรถูกจัดการเป็น issue ก็จริง แต่ส่วนใหญ่เป็น บันทึกสำหรับสิ่งที่มีลำดับความสำคัญต่ำหรือ edge case
- TODO ที่วางไว้อย่างเหมาะสมจะช่วยให้ผู้อ่านโค้ดในอนาคตมี เบาะแสในการเข้าใจเจตนาของผู้เขียนในตอนนั้น เมื่อต้องคิดว่า “ส่วนนี้รีแฟกเตอร์ได้ไหม?”
- คุณค่าของ TODO ไม่ได้อยู่ที่ ทำเสร็จหรือไม่ แต่อยู่ที่การบันทึก บริบท เจตนา และความเป็นไปได้ เพื่อช่วยการบำรุงรักษาและการทำงานร่วมกันในอนาคต
คอมเมนต์ TODO จำเป็นต้องจัดการเสมอไปไหม?
- ในบางองค์กรมีการใช้กฎให้ลงทะเบียน TODO ทุกอันในโค้ดไว้ใน bug tracker หรือให้ลบอัตโนมัติเมื่อผ่านไประยะหนึ่ง (มากกว่า 1 ปี)
- แต่แนวทางแบบนี้จริง ๆ แล้ว ไม่มีประสิทธิภาพ และมองข้ามธรรมชาติที่แท้จริงของ TODO — มันไม่ได้มีคุณค่าก็ต่อเมื่อถูก จัดการ เท่านั้น
คุณค่าที่แท้จริงของ TODO
-
ตัวอย่างเช่น
// TODO: 다음 주 출시 전에 이 파일의 뒷부분을 완성해야 함คอมเมนต์แบบนี้อาจจำเป็นต้องติดตามจริง
-
แต่ TODO ที่ดีมักจะเป็นลักษณะนี้
// TODO: 사용자가 이 버튼을 트리플 클릭할 경우, 핸들러에서 \[xyz] 오류 발생คือใช้เพื่อ บันทึก edge case หรือบันทึก ไอเดียในการปรับโครงสร้างที่ยังทำไม่ได้ตอนนี้ รวมถึงสถานการณ์ที่ตกหล่นไว้ พร้อมบริบท
TODO ไม่ใช่ “แผนงาน” แต่เป็น “ช่องทาง”
- TODO ส่วนใหญ่จริง ๆ แล้วเป็นเรื่อง ลำดับความสำคัญต่ำที่ไม่จำเป็นต้องทำทันที
- มันทำหน้าที่ ส่งต่อข้อกังวล การตัดสินใจ และบริบทของผู้เขียน ณ เวลานั้นไปยังผู้อ่านโค้ดในอนาคต
- เมื่อวันหนึ่งมีคนมาอ่านโค้ดแล้วสงสัยว่า “ตรงนี้เปลี่ยนโครงสร้างได้ไหม?” TODO จะช่วยให้เข้าใจ เจตนาของผู้เขียนในตอนนั้น
ผลลัพธ์ของ TODO ที่เขียนดี
- TODO ในโค้ดบางครั้งให้คำใบ้สำคัญเกี่ยวกับ ความเป็นไปได้ของปัญหา โอกาสในการปรับปรุงโครงสร้าง และ edge case ที่ยังไม่ได้จัดการ
- แม้จะไม่ใช่แผนสำหรับการแก้ไขเสมอไป แต่มันมีบทบาทอย่างมากในการ ส่งต่อบริบทที่ละเอียดอ่อน เพื่อการทำงานร่วมกันและการบำรุงรักษา
- ท้ายที่สุดแล้ว คอมเมนต์ TODO ก็เป็นบันทึกมีค่าที่ช่วยเพิ่ม ความเข้าใจโค้ด และ ความสามารถในการบำรุงรักษา ในอนาคต
บทสรุป
- TODO ไม่ได้มีคุณค่าก็ต่อเมื่อทำเสร็จเท่านั้น แต่เป็น ช่องทางสื่อสารที่ทิ้งความคิด เจตนา และบริบทของผู้เขียนไว้ให้ผู้อ่านโค้ดในอนาคต
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ผมคิดว่ามี 3 วิธีในการจัดการ TODO ก่อน merge
1. สร้าง issue ไว้—ถ้าเป็นงานที่ต้องทำจริง ก็ควรใช้เวลาสัก 20 วินาทีจดไว้และติดตามมัน
2. จัดการมันไปเลย—ถ้าเป็นเรื่องเล็กเกินกว่าจะสร้าง issue ก็ควรแก้ให้เสร็จก่อน commit
3. เปลี่ยนเป็นคอมเมนต์—ถ้าไม่คุ้มจะแก้และไม่จำเป็นต้องติดตาม แต่ยังอยากจำไว้ ก็แนะนำให้ทิ้งไว้เป็นคอมเมนต์โค้ดธรรมดา
ถ้าคิดถึงสุขภาพของโปรเจ็กต์ การมีนิสัยติดตาม TODO ก็เหมือนการกินบรอกโคลีเพื่อสุขภาพ
issue ที่อยู่ในระบบภายนอกอาจมองไม่เห็นชัดสำหรับนักพัฒนาที่กำลังแตะโค้ดส่วนนั้น
ถ้ารู้สึกว่าแม้แต่เรื่องที่แก้ได้ง่ายก็ยังไม่คุ้มกับต้นทุนของการติดตาม การปล่อยไว้เป็น TODO ก็มีประสิทธิภาพกว่า
TODO ในโค้ดจะมองเห็นได้ทันทีตอนทำงานกับโค้ดส่วนนั้น และลบออกได้ง่ายเวลาทำ refactor
แต่เสียดายที่ไม่ได้อธิบายความต่างระหว่าง TODO comment กับคอมเมนต์ทั่วไปให้ชัด
คำว่า TODO เองมีพลังทางสายตา ทำให้รู้ได้ทันทีว่าเป็นคอมเมนต์ประเภทไหน
การบอกว่าไม่จำเป็นต้องตีความ TODO comment ว่าเป็น "TO DO(สิ่งที่ต้องทำ)" ก็ดูชวนสงสัยอยู่เล็กน้อย
โดยรวมผมเห็นด้วยกับเนื้อหา แต่คิดว่าถ้าจะปรับปรุงจริง ๆ ก็สู้ใช้คอมเมนต์ธรรมดาไปเลยน่าจะดีกว่า
ถ้าเอาไปลงในระบบ ticket มันใช้เวลานานกว่า 20 วินาทีแน่ แถมไม่ได้ช่วยอะไรนัก กลับทำให้เสียสมาธิมากกว่า
// TODO: improve the routing https://jira.com/whatever/TIX-1234
เหตุผลคือถ้าคอมเมนต์กลายเป็นของไร้เจ้าของ สุดท้ายก็ไม่มีใครรู้ว่าทิ้งไว้ทำไม
ถ้าแค่ทิ้งคอมเมนต์ไว้ เผื่อเวลาผ่านไปใครสักคนก็จะลืมบริบทและจุดประสงค์
ดังนั้นผมจึงคิดว่าต้องสร้าง ticket ไม่ก็จัดการมันไปเลย
FIXME: จุดที่ผิดหรือพังอย่างชัดเจน ลำดับความสำคัญสูงสุด
XXX: จุดที่ดูไม่ดีหรือมีสมมติฐานผิด ๆ อยู่ ความสำคัญสูง
TODO: จุดที่วันหนึ่งควรมีการทำแนวทาง/หมวดหมู่/branch ใหม่ขึ้นมาอย่างสมบูรณ์
NOTE: ใช้สื่อสารข้อมูลที่สำคัญกว่าคอมเมนต์ธรรมดา
ผมทำงานกับ engine โค้ดเก่า/ไม่มีการดูแลเป็นหลัก และที่นี่ "โค้ดคือความจริง" เลยไม่ได้สร้าง JIRA แต่ค่อย ๆ อ่านแล้วแก้ไปตรงนั้นเลย
TODO: งานที่จำเป็นก่อน release เป็นสิ่งบังคับ ถ้าไม่เข้าเงื่อนไขนี้ก็ควรย้ายไปหมวดอื่น เป็นตัวบล็อก release
FUTURE: สักวันอาจกลายเป็น TODO ได้ โดยมากเป็นเรื่องเชิงสถาปัตยกรรมหรือการออกแบบที่เป็นตัวเลือก
MAYDO: มีก็ดี ไม่มีก็ได้
PERF: ควรทำเมื่อจำเป็นต้องการ performance เพิ่ม
และผมยังใช้แท็กเชิงความหมายที่เกี่ยวกับโดเมนด้วย
ความเห็นของผมคือ TODO ไม่ใช่ code smell แต่มันเป็นสิ่งที่ค่อย ๆ สะสมตามธรรมชาติในส่วนแกนกลางของ codebase
ถ้าจะเอาจริงก็สามารถตั้ง CI ให้ reject โค้ดที่มีสตริงนั้นได้
ในความหมายนี้ XXX จึงเป็นลำดับความสำคัญสูงสุดสำหรับผม
ถ้าเรียงลำดับความสำคัญลงมา
FIXME: เพื่อคงโฟกัส ต้องแก้ก่อนถึงจะ merge ได้หรือถือว่าโค้ดเสร็จ
XXX: ต้องแก้เร็ว ๆ นี้ ตอนนี้ยังทำงานได้ แต่ควรแก้ในเร็ววัน
TODO: ต้องกลับมาดูทีหลัง โค้ดยังใช้งานได้สมบูรณ์ ความสำคัญต่ำกว่า XXX
NOTE: อธิบายจุดพิเศษหรือสิ่งที่ควรรู้ เพื่อช่วยคนที่มาทำงานต่อ
TODO ใช้ทิ้งงานที่พอเป็นไปได้ เช่น การปรับ refactor/performance/clarity
NOTE ใช้ทิ้งข้อมูลจากอดีตหรือกระบวนความคิดที่มองตอนนี้แล้วอาจไม่เข้าใจทันที
ยิ่งถ้าสมมติว่าทำงานกันเป็นทีมก็ยิ่งจริง
ไม่ได้หมายความว่ามันไร้ค่านะ—ผมแค่มองว่าควรมีหรือควรสร้างเครื่องมือแบบนี้ขึ้นมา
technical debt หรือ code smell แบบนี้จริง ๆ ควรถูกติดตาม/บันทึก/อธิบายให้ดีกว่านี้ แต่ถ้าชวนให้ไปทำงานลด productivity แบบ JIRA สุดท้ายคนก็จะไม่บันทึกอะไรเลย
อย่างน้อยถ้ามี TODO อยู่ในโค้ด มันก็ยังถูกทิ้งร่องรอยไว้ที่ไหนสักแห่ง
TODO ก็ยังมีความหมาย เพราะมันคือ "สิ่งที่ต้องทำ" จริง ๆ
"ผมรู้ว่ามันทำให้ดีขึ้นได้ แต่จะไม่หยุด flow ของตัวเองเพื่อสิ่งนี้ ฟังก์ชันก็ไม่ได้พัง แค่ถ้ามีก็คงดีกว่า"
เวลาที่ไฮไลต์ TODO เด้งขึ้นมาใน editor บางครั้งมันช่วยให้หยิบมาจัดการได้ตอนที่อยากทำพอดี
แต่ TODO ส่วนใหญ่ก็มักอยู่ไปตลอดชีวิต หรือในความเป็นจริงแทบไม่เคยถูกแก้
ถึงจะไปลงใน JIRA, GH Issues ฯลฯ สุดท้ายก็ควรต้องมีการเชื่อมโยงกับบันทึกเหล่านั้น
และถ้าทิ้งไว้แค่ reference อย่างเดียว มันอาจเสียความหมายภายหลังได้ ดังนั้นในคอมเมนต์ก็ควรมีคำอธิบายประกอบด้วย
commit จำนวนมากจริง ๆ แล้วสื่อสารเนื้อหาได้ไม่ดี
แทนที่จะปล่อยให้ใช้ TODO แบบเก่า ๆ อยากให้ส่งเสริมการใช้เครื่องมือที่ดีกว่า
นักพัฒนาหลายคน commit น้อยเกินไป และชอบยัดหลายงานเข้ามาในครั้งเดียว
commit message เองก็มักเขียนแบบไม่มีความหมาย เช่น "updating somefile.py"
ใน codebase ของผม TODO ใช้ตามที่อธิบายไว้ที่นี่
TODO ใช้เพื่ออธิบายการ implement โดยเฉพาะการบันทึกส่วนที่ยังขาดอยู่—ไม่ได้แปลว่าต้องลงมือทำเสมอไป
ผมคิดว่าการทิ้งรายการงานจริงไว้ในโค้ดไม่ได้มีประโยชน์มากนัก เพราะลำดับความสำคัญเปลี่ยนตลอด สิ่งที่สำคัญตอนเขียนอาจไม่สำคัญแล้ว และบาง issue ที่ไม่ได้นึกถึงกลับกลายเป็นสิ่งที่ต้องทำทีหลังแทน
จะให้เปิด PR เรื่อย ๆ แค่เพื่ออัปเดต TODO comment ก็คงไม่ไหว
ถ้าอยากจดงานที่ต้องทำ ก็ควรไปจัดการในที่ภายนอก เช่น issue tracker หรือเอกสารข้อความที่อัปเดตได้ง่าย
เมื่อกี้ผมก็เพิ่งทิ้ง #TODO ไว้เพื่อบันทึกกรณียกเว้นที่เกิดขึ้นได้ยากมาก ผ่านมา 2 ปีก็ยังไม่เคยเกิดจริง แต่ถ้าวันหนึ่งผมสงสัยว่าทำไมตอนนั้นไม่จัดการส่วนนี้ไว้ มันก็จะช่วยได้
ผมก็เข้าใจคนที่บอกว่าของแบบนี้บางทีควรเป็นคอมเมนต์ธรรมดา ทั้งหมดขึ้นอยู่กับลักษณะของ codebase และในสภาพแวดล้อมอย่างทีม 2 คนแบบผม วิธี TODO ก็เวิร์กดี
// TBD: [...]สำหรับกรณีแบบนี้ เป็นลูกเล่นเพื่อไม่ให้คนที่ซีเรียสกับ TODO มากเกินไปสังเกตเห็นไม่ได้มีแผนจะแก้จริง ๆ แต่วันหลังถ้ามีเวลาว่างอาจอยากลองค้นด้วย ctrl-F ดูสักหนว่าพอเก็บงานส่วนนี้ได้ไหม
ผมคิดว่าเครื่องมือหรือกระบวนการจำนวนมากเกินไปที่มอง TODO เป็น code smell นั้นไม่สมเหตุสมผล
สำหรับผมมันเป็นเรื่องของลำดับความสำคัญ สุดท้ายก็เหมือน broken window (อุปมาชื่อดังจาก Pragmatic Programmer)
ถ้าตัดสินใจแล้วว่าจะไม่แก้จริง ๆ ก็ควรบันทึกไว้ในเอกสารของซอฟต์แวร์จะดีกว่า
ตัวอย่างเช่นถ้าเขียนแค่ว่า
// If the user triple-clicks this button, the click handler errors because [xyz]
แบบนี้จะไม่ชัดว่าเป็นบั๊ก หรือว่าเป็นพฤติกรรมที่ตั้งใจไว้
TODO เป็นสัญญาณสั้น ๆ ว่า "ตรงนี้ยังไม่สมบูรณ์นะ ไว้คำนึงถึงตอนทำงาน"
ถ้าเป็นสิ่งที่ต้องแก้จริง ๆ ก็ควรไปติดตามไว้ที่อื่น
แต่ถ้าพยายามลด TODO ลงมากเกินไป ผมกลับคิดว่าสุดท้ายจะยิ่งทำให้มีโค้ดที่ไม่มีเอกสารกำกับมากขึ้น
มีเวลาขนาดนั้นก็แก้บั๊กนั้นไปเลย หรือไม่ก็ทิ้งคอมเมนต์อย่าง "triple click จะถูกเพิกเฉยเพราะ [xyz]" ไว้แทน
ถ้ารู้ทั้งตัวกระตุ้นและสาเหตุแล้ว ผมถือว่างานเสร็จไปแล้ว 80%
ปัญหาคือเวลาที่โค้ดทำงานไม่สมบูรณ์แต่กลับมีการสมมติว่ามันสมบูรณ์
TODO ที่ดีที่สุดที่ผมเคยเห็นคือ "TODO: encrypt this" ซึ่งทิ้งไว้ในโค้ดด้านความปลอดภัยเพื่อบอกชัดว่ายังไม่ได้เข้ารหัส
เพราะมีอันนี้อยู่ ใคร ๆ ก็รู้ได้ทันทีว่าโค้ดยังไม่เข้ารหัส และยังช่วยลดความกังวลว่ามันอาจถูกจัดการเรื่องการเข้ารหัสแยกไว้ในโมดูลอื่น หรือจะเผลอเข้ารหัสซ้ำไหม
มันเป็นข้อผิดพลาดที่ชัดเจน แต่ในขณะเดียวกันก็ไม่ใช่เรื่องที่จำเป็นต้องจัดการมากนัก
ถ้าจะไม่ลงเป็นบั๊กหรือไม่คิดจะลงมือทำจริง ก็อย่าทิ้ง TODO ไว้เลย
// TODO: If the user triple-clicks this button, the click handler errors because [xyz]
อันนี้เป็นแค่การบันทึกอาการ ควรตัดคำว่า TODO ออก
FIXME ใช้เมื่อเป็นสิ่งที่ต้องแก้แน่ ๆ หรือเมื่อเห็นขั้นถัดไปชัดเจนแล้ว
TODO จะใช้กับความคิดที่ยังกว้างกว่า หรือแค่เอาออกจากหัวไว้ก่อนเพื่อจะได้ไปโฟกัสงานถัดไป
อาจเป็นตอนที่ไอเดียยังไม่สุกพอ ยังไม่มั่นใจว่าต้องทำจริง หรือกำลังรอบางอย่างที่เกี่ยวข้องอยู่
ถ้าไม่เขียนไว้ก็จะวนอยู่ในหัวจนรก แต่แค่จดออกมา ไม่ว่าจะเป็น TODO หรืออะไรก็ตาม ก็ช่วยให้โล่งขึ้นทางจิตใจมาก
ถ้าเขียนโค้ดให้เข้าใจได้ทันทีโดยไม่ต้องมีคอมเมนต์ก็คงดี
แต่ถ้ามันสับสนจนแม้แต่ผมเองมาอ่านทีหลังก็ยังไม่เข้าใจ สุดท้ายก็ต้องยอมเขียนคอมเมนต์
เรื่องน่าเศร้าคือถ้ามีใครมาแก้โค้ดภายหลังแต่ไม่อัปเดตคอมเมนต์ มันจะยิ่งทำให้สับสนกว่าเดิม
ผมคิดว่า TODO ไม่ควรอยู่ในโค้ดที่ commit แล้ว แต่ควรถูกจัดการในระบบบริหารโปรเจ็กต์หรือ issue tracker