- บทความนี้ไม่ใช่คำแนะนำ แต่เป็นการเขียนถึงนิสัยการพัฒนาที่ผู้เขียนกำลังนำมาใช้ในปัจจุบัน
- เป็นบทความที่สรุปประสบการณ์จากการพยายามหลีกเลี่ยงนิสัยที่ไม่ดีและสร้างนิสัยที่ดีขึ้น โดยกล่าวถึงนิสัย 10 ข้อที่ช่วยเพิ่มประสิทธิภาพการทำงานและรักษาคุณภาพ
1. รักษาให้คอมมิตมีขนาดเล็ก
- ควรรักษาให้คอมมิตเล็กที่สุดเท่าที่จะทำได้ คอมมิตเล็กช่วยให้เมื่อเกิดบั๊กสามารถย้อนกลับเฉพาะคอมมิตนั้นได้ และช่วยหลีกเลี่ยง merge conflict ที่ซับซ้อน
- ผู้เขียนยึดกฎว่า "ซอฟต์แวร์ควรอยู่ในสถานะที่คอมไพล์ได้เมื่อจะคอมมิต"
2. รีแฟกเตอร์อย่างต่อเนื่อง
- คำแนะนำของ Kent Beck: "เมื่อคุณต้องการเปลี่ยนแปลงบางอย่าง จงทำให้การเปลี่ยนแปลงนั้นทำได้ง่ายก่อน แล้วค่อยทำการเปลี่ยนแปลงที่ง่ายนั้น"
- อย่างน้อยครึ่งหนึ่งของคอมมิตควรมีการรีแฟกเตอร์รวมอยู่ด้วย รีแฟกเตอร์เล็กๆ ช่วยได้มากเมื่อมีความต้องการขนาดใหญ่เข้ามา
- ควรหลีกเลี่ยงการรีแฟกเตอร์ครั้งใหญ่ แต่ให้ทำการปรับปรุงเล็กๆ อย่างต่อเนื่องภายในเวลาไม่เกิน 10 นาที
3. ความสำคัญของการ deploy โค้ด
- ตัวโค้ดเองคือหนี้ที่อาจเกิดขึ้นได้ และโค้ดที่ยังไม่ได้ deploy คือหนี้ก้อนใหญ่ที่สุด
- การทดสอบช่วยสร้างความมั่นใจ แต่การ deploy จริงคือการยืนยันที่แท้จริง
- ยิ่ง deploy บ่อย ต้นทุนโฮสติ้งอาจเพิ่มขึ้น แต่การยืนยันได้ว่างานล่าสุดใช้งานได้จริงเป็นข้อดีที่สำคัญ
4. อย่าทดสอบความสามารถของเฟรมเวิร์ก
- ไม่ทดสอบความสามารถของเฟรมเวิร์ก เพราะเฟรมเวิร์กได้รับการตรวจสอบมาดีพอแล้ว
- หากรักษาให้คอมโพเนนต์มีขนาดเล็ก เฟรมเวิร์กจะจัดการงานส่วนใหญ่ให้ ทำให้ต้องเขียนเทสต์น้อยลง
- คอมโพเนนต์ขนาดใหญ่เพิ่มความซับซ้อน และจึงต้องมีการทดสอบจำนวนมากตามไปด้วย
5. สร้างโมดูลใหม่
- หากฟังก์ชันบางอย่างไม่เข้ากับโมดูลเดิม ก็ควรสร้างโมดูลใหม่จะดีกว่า
- การปล่อยให้มันเป็นโมดูลอิสระย่อมดีกว่าการยัดฟังก์ชันเข้าไปในโมดูลเดิมแบบฝืนๆ
6. ใช้การพัฒนาแบบขับเคลื่อนด้วยการทดสอบ (TDD) อย่างยืดหยุ่น
- หากการออกแบบ API ยังไม่ชัดเจน ให้เขียนเทสต์ก่อนเพื่อคิดจากมุมมองของ "ลูกค้า"
- ผู้เขียนไม่ได้ยึด TDD แบบเป็นหลักการเคร่งครัด หากจำเป็นก็สามารถทำงานเป็นหน่วยใหญ่ขึ้นก่อนแล้วค่อยทดสอบได้
- ไม่จำเป็นต้องทำให้โค้ดหน่วยเล็กอยู่ในสถานะล้มเหลวเสมอไป และไม่ยึดติดกับความเคร่งครัดที่บั่นทอนประสิทธิภาพการทำงาน
7. อนุญาตให้คัดลอกวางได้แค่ครั้งเดียว
- การคัดลอกครั้งเดียวไม่เป็นไร แต่ตั้งแต่ครั้งที่สองถือว่าเกิดความซ้ำซ้อนแล้ว
- ณ จุดนั้นควรกำจัดความซ้ำซ้อนด้วย abstraction ที่เหมาะสม แม้การทำให้เป็นพารามิเตอร์อาจดูแปลกไปบ้าง ก็ยังดีกว่าการเอาหลาย implementation มารวมกัน
8. ยอมรับการเปลี่ยนแปลงของดีไซน์
- ดีไซน์ย่อมเก่าลงตามกาลเวลา การรีแฟกเตอร์ช่วยชะลอความเสื่อมนี้ได้ แต่ท้ายที่สุดก็ต้องเปลี่ยนอยู่ดี
- อย่ายึดติดกับดีไซน์เดิมมากเกินไป และควรยอมรับการเปลี่ยนแปลง
- ไม่มีดีไซน์ที่สมบูรณ์แบบ และความสามารถในการรับมือกับการเปลี่ยนแปลงคือหัวใจของการพัฒนาซอฟต์แวร์
9. หนี้ทางเทคนิค 3 ประเภท
- หนี้ทางเทคนิคสามารถแบ่งได้เป็น 3 ประเภท:
- สิ่งที่ขัดขวางงานปัจจุบัน
- สิ่งที่อาจขัดขวางงานในอนาคต
- สิ่งที่อาจจะขัดขวางก็ได้
- ควรลดหนี้ประเภทแรกให้เหลือน้อยที่สุด มุ่งเน้นที่ประเภทที่สอง และมองข้ามประเภทที่สาม
10. ความสัมพันธ์ระหว่างการทดสอบได้กับการออกแบบที่ดี
- ถ้าทดสอบได้ยาก ก็มีความเป็นไปได้สูงว่าการออกแบบมีปัญหา
- การออกแบบเทสต์เองก็อาจเป็นสิ่งที่ต้องปรับปรุงได้ เช่น หากรู้สึกว่ายากที่จะเขียน mock สำหรับ
em.getRepository(User).findOneOrFail({id}) ก็ควรแยกออกเป็นฟังก์ชันต่างหาก หรือใช้ test utility
- สาเหตุที่ไม่มีการเขียนเทสต์ มักเป็นเพราะมันทดสอบยาก และนั่นอาจเป็นปัญหาด้านการออกแบบ
9 ความคิดเห็น
ดูเหมือนว่าต้องทำให้บรรลุ
SRPมากกว่าDRYถึงจะฝากให้ AI ทำแล้วไม่พูดเพ้อเจ้อผมคิดว่าสิ่งที่สำคัญที่สุดคือคุณสร้างโค้ดและสภาพแวดล้อมที่สามารถปรับตัวต่อการเปลี่ยนแปลงได้รวดเร็วแค่ไหน
และด้วยการทำ abstraction ที่เหมาะสม ก็สามารถเพิ่มการนำโค้ดกลับมาใช้ซ้ำและความสามารถในการขยายต่อได้ พร้อมทั้งใช้เครื่องมือ AI เพื่อเร่งความเร็วในการพัฒนาให้สูงสุดได้
เป็นบทความที่ดีมากจริง ๆ อยากแนะนำต่อไปทั่วเลย
ยอมรับการเปลี่ยนแปลง, คัดลอก-วางแค่ครั้งเดียว, ทำให้เทสต์ทำงานได้ดีขึ้น, คอมมิตให้เล็กลง...!
เป็นบทความที่ดีนะ
บทความนี้น่าจะดีมากถ้าได้ไปดูต้นฉบับกันด้วยนะครับ
ปกติถ้าเป็นข่าวที่ผมสนใจก็มักจะไปดูต้นฉบับอยู่แล้ว แต่เรื่องนี้ยิ่งควรทำแบบนั้น โดยเฉพาะถ้าดูข้อ 1 ต้นฉบับเขียนไว้ว่า
Keep commits small enough that you wonder if you're taking this "keep commits small" thing a little too far. แต่ถูกย่อสรุปเป็นว่า "ควรรักษาให้คอมมิตเล็กที่สุดเท่าที่จะทำได้" เลยนะ..
เป็นบทความที่ดีมากจริง ๆ
ข้อ 7 ดีมากจริง ๆ
ความคิดเห็นจาก Hacker News
ควรใช้พารามิเตอร์เพื่อหลีกเลี่ยงการทำหลาย implementation การปรับปรุงพารามิเตอร์ทำได้ง่ายกว่าการรวมหลาย implementation เข้าด้วยกัน
การคัดลอกโค้ดครั้งเดียวอาจพอรับได้ แต่ตั้งแต่ครั้งที่สองเป็นต้นไปควรหลีกเลี่ยงความซ้ำซ้อน ควรสร้าง abstraction ที่ดีเมื่อมี data point มากพอ
DRY (อย่าทำซ้ำ) หรือ WET (เขียนทุกอย่างสองครั้ง) ไม่ใช่กฎตายตัว ปัญหาที่ยากคือการเข้าใจเรื่องความซ้ำซ้อนของโค้ดและจังหวะที่ควรรวมมันเข้าด้วยกัน
แทนที่จะทำ commit เล็ก ๆ อย่างเดียว อีกทางเลือกหนึ่งคือสามารถเพิ่ม commit ใหม่เพื่อแก้บั๊กได้โดยไม่ต้อง revert commit ใหญ่
ความสามารถในการทดสอบเกี่ยวข้องกับการออกแบบที่ดี สิ่งที่ทดสอบได้ไม่ง่ายอาจเป็นสัญญาณว่าจำเป็นต้องเปลี่ยนการออกแบบ
ควรระวังเมื่อทดสอบความสามารถของ framework เพราะ framework อาจเปลี่ยนไปตามเวลา
สำหรับขนาดของ commit ควรมุ่งไปที่ commit ที่ revert ได้ง่าย เผื่อกรณีที่ต้องย้อนการเปลี่ยนแปลงบางอย่าง
บริษัทต่าง ๆ ต้องการ codebase ที่เสถียร แต่ก็ยังต้องมีการ refactor อย่างต่อเนื่อง ซึ่งอาจขัดแย้งกับความเสถียรได้