- สรุปบางช่วงจากบทสัมภาษณ์ Programmatic Engineer ของ Kent Beck ผู้เป็นบิดาแห่ง XP และ TDD ที่น่าประทับใจสำหรับผม
- ถ้าคุณชอบ Kent Beck แนะนำให้ดูวิดีโอฉบับเต็ม
Q. แก่นสำคัญของ XP คืออะไร?
คือการทำ 4 กิจกรรมต่อไปนี้
- ทำความเข้าใจว่าต้องทำอะไร
- ทำความเข้าใจโครงสร้างที่จะทำให้เราทำข้อ 1 ได้
- ใช้ข้อ 2 เพื่อพัฒนาข้อ 1 ขึ้นมา
- ตรวจสอบว่าข้อ 3 ทำงานตามที่คาดไว้หรือไม่
มีแค่นี้เอง แล้วก็แบ่งเวลาให้ย่อยมาก ๆ เพื่อให้ในทุกชั่วโมงเราได้ทำทั้ง 4 กิจกรรมนี้ทีละนิด แต่ทำครบทั้งหมด
Q. ถ้าอย่างนั้น pair programming ก็ไม่ใช่สิ่งจำเป็นใน XP ใช่ไหม?
ตอนที่เริ่มบริหารทีม XP เป็นครั้งแรก เราปล่อยระบบทุก 3 สัปดาห์ และแน่นอนว่ามีบั๊ก
พอลองวิเคราะห์แพตเทิร์นของบั๊กที่ถูกพบ 'หลังปล่อยระบบ' ก็พบว่าบั๊กทั้งหมดนั้นเกิดจากโค้ดที่ พัฒนาโดยคนเดียว พูดกลับกันคือ ในโค้ดที่พัฒนาแบบ pair ไม่พบ defect ที่ถูกรายงานจาก production เลย
Q. งั้นก็ไม่ถึงกับบังคับ แต่เป็นสิ่งที่แนะนำอย่างมาก?
ก็ไม่ใช่อีก สิ่งที่อยากบอกคือให้ทดลอง คุณจะพัฒนาแบบเดิมที่เคยทำมาก็ได้ แต่อย่าหลับหูหลับตาทำ
ไม่ว่าจะเป็น continuous design, continuous verification, continuous implementation หรือ continuous interaction กับลูกค้า ถ้าคุณอยากได้ประโยชน์จากสิ่งเหล่านี้ แต่ทำแบบเดิมซ้ำ ๆ แล้วมันไม่ได้ผล งั้นก็ต้องเปลี่ยนวิธี
ถ้ามีใครมาบอกผมว่า "Kent, ผมไม่ทำ TDD" ผมก็จะตอบว่า "แล้วไง?"
ถ้าคุณพอใจกับ defect density ในโค้ดของตัวเองตอนนี้ และพอใจกับระดับ feedback ที่ได้ต่อการตัดสินใจด้านการออกแบบ ก็ไม่มีปัญหา แต่ถ้าไม่พอใจ ก็ลองทั้ง pair หรือ TDD ดู
Q. ไหน ๆ ก็พูดถึงแล้ว ทำไมถึงสร้าง TDD ขึ้นมา?
ผมเป็นคนที่กังวลมากและค่อนข้างวิตก และสำหรับผม การเขียนโปรแกรมคือแหล่งกำเนิดความกังวลไม่รู้จบ ผมลืมอะไรไปหรือเปล่า? ผมทำอะไรพังไปหรือเปล่า?
แต่พอพัฒนาแบบ TDD ความกังวลนี้ก็หายไป ถ้านึก test case ที่น่าจะ fail เพิ่มไม่ออกแล้ว ก็แปลว่าผมมั่นใจได้ว่าโปรแกรมทำงาน ถ้าเริ่มรู้สึกกังวลขึ้นมาแม้แต่นิดเดียว ก็แค่เขียน test case ถัดไป
แน่นอนว่า TDD มีประโยชน์ทางเทคนิคมากมาย เช่น ลด defect density, ได้ feedback ต่อการตัดสินใจด้านการออกแบบเร็วขึ้น, ทำให้ implementation design ค่อย ๆ evolve ได้ แต่สำหรับผม สิ่งสำคัญที่สุดคือการหลุดพ้นจากความกังวลเกี่ยวกับการเขียนโปรแกรม และประสบการณ์ทางอารมณ์ที่การเขียนโปรแกรมมอบให้ได้เปลี่ยนไปอย่างสิ้นเชิง นี่แหละคือเหตุผลที่ผมสร้าง TDD
Q. คุณคิดอย่างไรกับคำวิจารณ์ของ John Ousterhout ที่บอกว่าถ้าทำ TDD จะไม่มีช่องว่างให้การออกแบบที่ดีเข้ามาแทรก?
(หมายเหตุผู้แปล: John Ousterhout เป็นผู้เขียนหนังสือคลาสสิก Philisophy of Software Design และเมื่อไม่กี่เดือนก่อนก็ไปออกรายการ พอดแคสต์ Programmatic Engineer พร้อมแสดงมุมมองวิจารณ์ TDD ด้วย)
เขาเข้าใจผิดอยู่ส่วนหนึ่ง มันเป็นเพียงผลลัพธ์ของการตัดสินใจเท่านั้น ถ้าคุณปฏิบัติกับ TDD แค่ในฐานะการวนซ้ำแบบ Red-Green อย่างเดียว แน่นอนว่ามันจะไม่มีที่ให้การออกแบบแทรกเข้ามา
ในฐานะผู้ปฏิบัติ TDD ผมสลับไปมาระหว่างระดับของ abstraction อยู่ตลอดเวลา ตัวอย่างเช่น:
- ตอนนี้อยู่ในสถานะ Red ถ้าจะทำให้ test case ถัดไปผ่าน (Green) ต้อง implement ยังไง?
- มันดูยากจัง ทำไมถึงยาก?
- ถ้าจะทำให้ implementation เพื่อไป Green ง่ายขึ้น ควรเปลี่ยน design ยังไง?
- ควรใส่ไอเดียนั้นเมื่อไร ตอนนี้หรือทีหลัง?
- ถ้าจะใส่ตอนนี้ ควรใส่แค่ไหน ทำเท่าที่พอทำได้ตอนนี้นิดหน่อย หรือทำเป็นก้อนใหญ่กว่านี้?
พูดอีกอย่างคือ ก่อนเขียนเทสต์ ผมจะมีช่วงเวลาของการออกแบบเสมอ
ก่อนลงมือ implement ผมจะตัดสินใจเรื่อง interface ก่อน แล้วสร้าง Red test ขึ้นมา และเพราะผมไม่ชอบสถานะ Red ผมจึงทำให้มันเป็น Green ให้เร็วที่สุด พอเป็น Green แล้ว ความกังวลจะหายไปชั่วคราว ทำให้มีพื้นที่ให้คิดว่า 'อืม มันผ่านก็จริง แต่กับเคสอื่นคงใช้ไม่ได้ ต้องทำ implementation ให้ general กว่านี้'
Red อยู่เหรอ? ทำให้เป็น Green สิ Green แล้วเหรอ? หายใจแล้วคิด นี่คือวงจร TDD ของผม
Q. บางครั้งผมรู้สึกว่า implementation มันชัดเจนมาก เลย implement ก่อนแล้วค่อยไปทำ Red-Green test ทีหลัง คุณคิดยังไงกับวิธีนี้?
นั่นอาจเป็นเพราะคุณกำลังตั้งสมมติฐานว่า 'วิธี implement นี้ถูกต้อง' และยิ่งสมมติฐานนั้นถูกมากเท่าไร ประโยชน์ของการเขียนเทสต์ก่อนก็ยิ่งลดลงเป็นธรรมดา
แต่ผมคิดแบบนี้เสมอว่า "ผมจะเรียนรู้และเก็บประสบการณ์ต่อไปเรื่อย ๆ และตอนนี้คือช่วงที่ผมรู้น้อยที่สุด"
นั่นคือผมตั้งสมมติฐานว่าตัวเองจะเรียนรู้อยู่เรื่อย ๆ และสถานการณ์ก็จะเปลี่ยนไป ยิ่งผมต้องเรียนรู้อีกมากและยิ่งสถานการณ์เปลี่ยนได้มากเท่าไร ผมก็ยิ่งอยากเลื่อนการตัดสินใจออกไปให้นานที่สุด นี่เป็นหลักการทั่วไป ไม่ว่าจะเรื่องเดตหรือเรื่องทำอาหารก็เหมือนกัน
ถ้าคาดเดาได้มากขึ้น คุณก็สามารถกระโดดครั้งใหญ่ได้มากขึ้น แต่ช่วงเวลาที่ผมรักที่สุดในการเขียนโปรแกรมคือ ตอนที่ผมคิดว่าตัวเองรู้หมดแล้วและกำลังเดินหน้าอย่างลื่นไหล แต่จู่ ๆ ก็พบว่ามีวิธี implement ที่ดีกว่ามากอยู่ ผมอยากเจอช่วงเวลาแบบนี้ให้บ่อยที่สุดเท่าที่จะทำได้ นั่นจึงเป็นเหตุผลที่ผมทำ TDD
ถ้าในหัวเห็นภาพชัด และมั่นใจได้ว่า input แบบไหนจะให้ output แบบไหน ก็ implement ไปเลยได้ แต่ยิ่งคุณทำพลาดมากขึ้น ยิ่งได้เรียนรู้มากขึ้น และยิ่งโลกเปลี่ยนแบบคาดเดาไม่ได้มากขึ้น การไม่ผูกมัดตัวเองตอนนี้และเลื่อนไปตัดสินใจทีหลังจะยิ่งคุ้มกว่า
Q. ตอนเขียนโค้ดร่วมกับ AI คุณยังพัฒนาแบบ TDD เหมือนเดิมไหม?
ตอบสั้น ๆ ได้ยาก
ผมใช้เทสต์เป็นเครื่องมือสื่อสารกับ AI และส่วนใหญ่ใช้เป็นวิธีบอกว่า AI ทำอะไรผิด เจ้าตัวนี้ชอบลบหรือแก้เทสต์ของผมอยู่เรื่อย แล้วผมก็ต้องดุมันทุกครั้งว่า เทสต์ของผมถูกแล้ว ทำให้ถูกสิ
AI มักจะตัดสินใจที่ไม่ดีในระยะยาว มันทำเรื่องลด coupling และเพิ่ม cohesion ได้แย่มาก ถ้าบอกงานให้ชัดมาก ๆ มันก็พอทำได้ แต่โดยทั่วไปต้องถือว่ามันออกแบบไม่เก่ง
เพราะงั้นผมเลยเตรียมเทสต์ไว้เยอะมาก ใช้มันเป็นเครื่องมือจับว่า AI กำลังทำอะไรพังอยู่หรือเปล่า
(หมายเหตุผู้แปล: ถ้าอยากดูว่า Kent Beck ใช้ TDD กับ vibe coding อย่างไร ลองดูบทความนี้)
Q. ถ้ากฎสำหรับเอเจนต์อย่างเช่น ห้ามแก้เทสต์เด็ดขาด ถ้าเทสต์ไม่ผ่านก็ให้แก้เฉพาะโค้ด implementation จนกว่าจะผ่าน กลายเป็นมาตรฐานน่าจะสะดวกขึ้น คุณคิดว่านี่เหมือนช่วงเวลาที่เรากำลังค้นพบสิ่งสำคัญในยุค 2000 อีกครั้งไหม?
เราต้องทดลองต่อไป ต้องลองทุกอย่างที่เป็นไปได้ เพราะตอนนี้เรายังไม่รู้ว่าอะไรดีที่สุดจริง ๆ
ขอบเขตของคำว่าอะไร 'ถูก' และอะไร 'แพง' เปลี่ยนไปอย่างสิ้นเชิง หลายอย่างที่เมื่อก่อนเคยมองว่าแพงหรือยากจนไม่ทำ ตอนนี้กลับถูกลงอย่างน่าเหลือเชื่อ
ถ้าวันหนึ่งรถยนต์กลายเป็นของฟรีขึ้นมาทันที คุณคิดว่าจะเกิดอะไรขึ้น? แน่นอนว่ามันต้องมีบางอย่างเปลี่ยน แต่ผลกระทบลำดับที่สอง ลำดับที่สามจะเป็นอย่างไร? ไม่มีใครคาดเดาได้ เพราะงั้นตอนนี้เราก็ทำได้แค่ลองหลาย ๆ อย่าง
Q. คุณบอกว่าตลอดเวลากว่า 50 ปีของการเขียนโปรแกรม ตอนนี้สนุกที่สุด หมายความว่าอย่างไร?
การทำให้ไอเดียใหญ่ ๆ ของผมเป็นจริงนั้นง่ายกว่าที่เคยมาก การเฝ้าดูว่า AI จะ implement ไอเดียนี้ได้ไหม และจะ implement ยังไง พร้อมกับคอยปรับมันไปด้วย เป็นอะไรที่เสพติดมาก มันไม่รู้ว่าจะเวิร์กเมื่อไร และเวลาที่มันเวิร์กแบบมหัศจรรย์ก็ชวนเคลิบเคลิ้ม คล้ายสล็อตแมชชีน ผมเลยมักถูกครอบงำด้วยความอยากจะทิ้ง prompt ไว้สักอันก่อนออกไปเดินเล่นหรือไปกินข้าวกลางวัน เพื่อไม่ให้เจ้าตัวนี้อยู่ว่าง ๆ
เมื่อ 2 ปีก่อน ผมเคยทวีตไว้ว่า "ผมลังเลที่จะลองใช้ ChatGPT และวันนี้ก็ข้ามความลังเลนั้นมาได้ ตอนนี้ผมเข้าใจแล้วว่าทำไมถึงลังเล มูลค่าของทักษะ 90% ที่ผมมี ลดลงเหลือ $0 ไปแล้ว และอีก 10% ที่เหลือกลับมีแรงทวีคูณเพิ่มขึ้น 1000 เท่า ถึงเวลาที่ผมต้องปรับเทียบทักษะของตัวเองใหม่" ในทวีตนี้
> I've been reluctant to try ChatGPT. Today I got over that reluctance. Now I understand why I was reluctant.
>
> The value of 90% of my skills just dropped to $0. The leverage for the remaining 10% went up 1000x. I need to recalibrate.
>
> -- Kent Beck 🌻 (@KentBeck) April 18, 2023
(หมายเหตุผู้แปล: ตอนนั้นพอทวีตนี้กลายเป็นประเด็น Kent ก็เขียนบทความที่ยาวขึ้นอีกหน่อย ไว้ด้วย)
ตอนนั้นผมบอกว่ายังอยู่ระหว่างสำรวจว่า 90% คืออะไร และ 10% คืออะไร แต่ตอนนี้พอตอบได้บ้างแล้ว การมีวิสัยทัศน์ที่กล้าหาญ การตั้ง milestone เพื่อมุ่งสู่วิสัยทัศน์นั้น และทักษะในการปรับ design ไปพร้อมกับเดินหน้าโดยยังควบคุมความซับซ้อนได้ สิ่งเหล่านี้สำคัญกว่าความรู้เรื่องไวยากรณ์ของภาษาใดภาษาหนึ่งมาก (เช่น ใน Rust ต้องใส่ &, *, [ ตรงไหน)
ยังไม่มีความคิดเห็น