Death by Planning
วางแผนจนไม่ได้ส่งมอบ — จำไว้ว่า “การส่งมอบคือ feature”
ปัญหาคืออะไร
หัวข้อที่มีชื่อว่า “ปัญหาคืออะไร”Death by Planning คือแอนตี้ pattern ระดับการบริหารโครงการ (management antipattern) ที่เกิดขึ้นเมื่อทีมหรือผู้บริหารโครงการ “เอาแผนจริงจังเกินไป” — พยายามคาดการณ์และจัดตารางรายละเอียดทุกอย่างล่วงหน้า ทั้งขอบเขตงาน (scope) ระยะเวลา ทรัพยากร และลำดับขั้นตอน ก่อนที่จะลงมือเขียน code แม้แต่บรรทัดเดียว ผลคือทีมพัฒนาใช้เวลาส่วนใหญ่ไปกับการวางแผน ประชุม เขียนเอกสาร และปรับปรุงตารางงาน จนไม่เหลือเวลาพอสำหรับการ “สร้างจริง”
ต้นตอของปัญหานี้มาจากการยืมกรอบคิดของอุตสาหกรรมที่งานคาดการณ์ได้สูง เช่น การก่อสร้างหรือการผลิต มาใช้กับซอฟต์แวร์ ซึ่งโดยธรรมชาติเต็มไปด้วยสิ่งที่ไม่รู้ (unknowns) และความไม่แน่นอนที่ค้นพบระหว่างทาง การวางแผนแบบละเอียดยิบล่วงหน้าจึงมักไม่สอดคล้องกับความเป็นจริงของงานพัฒนาซอฟต์แวร์
Death by Planning มีความสัมพันธ์ใกล้ชิดกับ Analysis Paralysis และ Big Design Up Front (BDUF) — ทั้งสามล้วนเป็นอาการของการ “คิดมากกว่าทำ” แต่ Death by Planning เน้นเฉพาะมิติของการบริหารจัดการโครงการ (การจัดตารางงาน การประชุม การรีแพลนซ้ำ ๆ) มากกว่ามิติของการออกแบบทางเทคนิคหรือการวิเคราะห์ความต้องการ
ทำไมถึงดูน่าใช้
หัวข้อที่มีชื่อว่า “ทำไมถึงดูน่าใช้”การวางแผนละเอียดดูสมเหตุสมผลเพราะ:
- ให้ความรู้สึกควบคุมได้ ผู้บริหารและผู้มีส่วนได้ส่วนเสียอยากเห็นตารางงาน วันส่งมอบ และงบประมาณที่ชัดเจนตั้งแต่ต้น การมีแผนละเอียดทำให้รู้สึกว่าความเสี่ยงถูกจัดการแล้ว
- อ้างอิงต้นทุนของการเปลี่ยนแปลง แนวคิดดั้งเดิมเชื่อว่าเส้นโค้งต้นทุนของการแก้ไข (cost-of-change curve) พุ่งขึ้นแบบทวีคูณ — ความผิดพลาดที่แก้ตอนวิเคราะห์ราคาถูกกว่าการแก้ตอน production มาก ดังนั้นการคิดให้รอบคอบก่อนลงมือจึงดูเหมือนเป็นการลงทุนที่คุ้มค่า
- ลดความกลัวการทำผิดพลาดที่แก้ยาก โดยเฉพาะในโครงการขนาดใหญ่ หรือระบบที่เปลี่ยนแปลงยาก (เช่น ฮาร์ดแวร์ฝังตัว หรือระบบเก่าที่ deploy ยาก) การวางแผนล่วงหน้าจึงดูเป็นการป้องกันความเสี่ยงที่สมเหตุสมผล
- สอดคล้องกับวัฒนธรรมองค์กรที่เน้นความรับผิดชอบ (accountability) แผนที่ละเอียดทำให้ตรวจสอบความคืบหน้าได้ง่าย และดูเหมือนสร้างความโปร่งใสให้ผู้บริหารระดับสูง
ทำไมถึงเป็นปัญหา
หัวข้อที่มีชื่อว่า “ทำไมถึงเป็นปัญหา”ปัญหาคือซอฟต์แวร์ไม่ได้มีลักษณะเหมือนงานก่อสร้างที่ทำนายได้แม่นยำ:
- ต้นทุนของการวางแผนสะสมโดยไม่สร้างคุณค่า ทุกชั่วโมงที่ใช้วางแผนคือชั่วโมงที่ไม่ได้ใช้สร้างซอฟต์แวร์ที่ใช้งานได้จริง และอย่าลืมว่าการประชุม 6 คนหนึ่งชั่วโมงมีต้นทุนต่อบริษัทไม่น้อยเลย — ยิ่งประชุมวางแผนบ่อยและนานเท่าไร ต้นทุนแฝงนี้ก็ยิ่งสูงขึ้น
- แผนล้าสมัยเร็วกว่าที่คิด ความต้องการทางธุรกิจเปลี่ยนแปลงเร็วกว่าที่โครงการขนาดใหญ่จะทำเสร็จ ทำให้แผนที่ “สมบูรณ์แบบ” ณ วันแรกกลายเป็นสิ่งล้าสมัยก่อนถึงวันส่งมอบจริง
- ขาด feedback loop จากของจริง การวางแผนล้วน ๆ ไม่มีการ implement หรือ deploy มายืนยันสมมติฐาน ทำให้ทีมค้นพบปัญหาช้าเกินไป เมื่อค้นพบก็ต้องรีแพลนใหม่ วนเป็นวงจรไม่รู้จบ
- บั่นทอนขวัญกำลังใจทีมพัฒนา เมื่อทีมเห็นว่างานของตัวเองคือการนั่งประชุมและปรับตารางงานซ้ำ ๆ แทนที่จะได้เห็นผลงานจริงถูกใช้งาน แรงจูงใจในการทำงานก็ลดลง
- สมมติฐานที่ผิดเกี่ยวกับความสามารถในการคาดการณ์ งานซอฟต์แวร์เต็มไปด้วยสิ่งไม่รู้ (unknown unknowns) การพยายามกำหนดทุกรายละเอียดล่วงหน้าจึงมักอิงอยู่บนสมมติฐานที่ผิดตั้งแต่ต้น และแผนที่ดูละเอียดยิบกลับยิ่งเปราะบางเมื่อความจริงไม่ตรงกับที่วางไว้
ตัวอย่าง
หัวข้อที่มีชื่อว่า “ตัวอย่าง”สมมติทีมกำลังจะสร้างระบบจัดการคำสั่งซื้อ (order management) ใหม่ ภายใต้อิทธิพลของ Death by Planning ทีมอาจใช้เวลาหลายสัปดาห์เขียนเอกสาร spec interface ทุกตัวไว้ล่วงหน้า ก่อนที่จะรู้ด้วยซ้ำว่า workflow จริงของธุรกิจเป็นอย่างไร
// แอนตี้ pattern: interface ถูกออกแบบละเอียดยิบล่วงหน้า// ตาม spec ที่ผ่านการประชุมวางแผน 3 เดือน โดยยังไม่เคยรัน// code จริงหรือคุยกับผู้ใช้งานเลยสักครั้งpublic interface IOrderProcessingPipeline{ ValidationResult ValidateOrder(Order order, ValidationRuleSet rules); PricingResult ApplyPricingRules(Order order, PricingContext context); InventoryReservation ReserveInventory(Order order, WarehouseSelectionStrategy strategy); PaymentAuthorization AuthorizePayment(Order order, PaymentGatewayConfig config); ShippingLabel GenerateShippingLabel(Order order, CarrierNegotiationResult carrier); // ...อีก 12 method ที่ระบุไว้ในเอกสาร spec 40 หน้า}
// สามเดือนต่อมา เมื่อเริ่ม implement จริง ทีมพบว่า// ธุรกิจไม่มี "WarehouseSelectionStrategy" แบบที่วางแผนไว้// เพราะมีคลังสินค้าเดียว และ "CarrierNegotiationResult"// ก็ไม่เคยถูกใช้เพราะบริษัทใช้ผู้ให้บริการขนส่งรายเดียว// ต้องรื้อ spec ทั้งหมดใหม่ ก่อนจะเขียน code ได้แม้แต่บรรทัดแรกในทางกลับกัน ทีมที่หลีกเลี่ยง Death by Planning จะวางแผนแค่พอให้เริ่มงานได้ และปล่อยให้รายละเอียดค่อย ๆ ชัดเจนขึ้นจากการ implement จริง:
// ทางแก้: เริ่มจาก interface ขั้นต่ำที่จำเป็นต่อ use case แรก// แล้วปล่อยให้ขยายตามความต้องการจริงที่พิสูจน์แล้วว่ามีอยู่public interface IOrderProcessor{ OrderResult Process(Order order);}
public class OrderProcessor : IOrderProcessor{ public OrderResult Process(Order order) { // เริ่มจาก flow ง่ายที่สุดที่ยัง deliver คุณค่าได้จริง // ตรวจสอบ, จองสต๊อก, และเรียกเก็บเงิน // เพิ่ม pricing rules, ผู้ให้บริการขนส่งหลายราย ฯลฯ // ในภายหลังเมื่อธุรกิจต้องการจริง ๆ (ดู YAGNI) return new OrderResult(OrderStatus.Confirmed); }}แนวทางนี้สอดคล้องกับสิ่งที่ Martin Fowler เรียกว่า evolutionary design — ให้สถาปัตยกรรมค่อย ๆ ปรากฏขึ้นจากการ implement จริง แทนที่จะกำหนดไว้ตายตัวล่วงหน้าเหมือนแบบแปลนตึกที่ต้องสมบูรณ์ก่อนก่อสร้าง
ทางแก้และการ refactor
หัวข้อที่มีชื่อว่า “ทางแก้และการ refactor”หลักการสำคัญคือ ให้แผนระยะสั้นใกล้เคียงกับการ implement จริงที่สุด และให้แผนระยะยาวคลุมเครือและยืดหยุ่นที่สุด วิธีปฏิบัติที่ช่วยได้:
- แบ่งงานเป็นชิ้นเล็ก แล้วส่งมอบเป็นรอบสั้น ๆ — แนวทางที่อุตสาหกรรมเรียกกันว่า iterative development หรือ Agile นี่คือคำตอบโดยตรงต่อ Death by Planning เมื่อรอบวางแผน-สร้าง-ส่งมอบสั้นลง ต้นทุนของการวางแผนผิดก็เล็กลงตามไปด้วย
- จำไว้ว่า Shipping Is A Feature — การส่งมอบของจริงให้ผู้ใช้เห็นและใช้งานได้ มีค่ามากกว่าการมีแผนที่สมบูรณ์แบบบนกระดาษ
- Update the Plan อย่างสม่ำเสมอแทนการวางแผนใหญ่ครั้งเดียว — ปรับแผนเป็นระยะสั้น ๆ ตามข้อมูลจริงที่ได้จากการส่งมอบรอบก่อนหน้า แทนที่จะพยายามคาดการณ์ทุกอย่างตั้งแต่วันแรก
- ใช้ YAGNI — อย่าออกแบบหรือวางแผนรองรับ feature ที่ยังไม่พิสูจน์ว่าจำเป็นจริง ลดขอบเขตของสิ่งที่ต้องวางแผนลงไปในตัว
- ลดต้นทุนการประชุม — จำกัดจำนวนคนและเวลาของการประชุมวางแผน ตั้งคำถามเสมอว่า “การประชุมนี้คุ้มกับเวลาที่ใช้ไปหรือไม่ เทียบกับการเอาเวลานั้นไปสร้างของจริง”
- ลงทุนใน practice ที่ทำให้ evolutionary design ปลอดภัย — automated test, continuous integration และการ refactor ที่ดี ช่วยทำให้เส้นโค้งต้นทุนของการเปลี่ยนแปลง (cost-of-change curve) แบนราบลง ทำให้ทีมกล้าเริ่มสร้างโดยไม่ต้องวางแผนทุกรายละเอียดล่วงหน้า เพราะมั่นใจว่าแก้ไขทีหลังได้โดยไม่แพงเกินไป
flowchart TD
Start[เริ่มโครงการ] --> ShortPlan[วางแผนระยะสั้น ใกล้ implementation]
ShortPlan --> Build[สร้างและส่งมอบชิ้นเล็ก]
Build --> Feedback[รับ feedback จากของจริง]
Feedback --> UpdatePlan[ปรับปรุงแผนตามข้อมูลจริง]
UpdatePlan --> ShortPlan
LongPlan[แผนระยะยาว คลุมเครือและยืดหยุ่น] -.-> ShortPlan