Waterfall
วิธีพัฒนาแบบขั้นตอนตายตัว ที่ผู้เสนอตั้งใจให้เป็นตัวอย่าง “สิ่งที่ไม่ควรทำ”
ปัญหาคืออะไร
หัวข้อที่มีชื่อว่า “ปัญหาคืออะไร”Waterfall (บางคนเรียกเชิงประชดว่า “Waterfail”) เป็นระเบียบวิธีวงจรชีวิตซอฟต์แวร์ที่ แข็งทื่อและไหลไปในทิศทางเดียว โดยดันกิจกรรมทั้งหมดผ่านชุดขั้นตอนตายตัวเรียงต่อกันเป็นเส้นตรง แต่ละขั้นต้อง “ปิด” ให้เสร็จสมบูรณ์และผ่านการอนุมัติก่อน จึงจะอนุญาตให้เริ่มขั้นถัดไป ลำดับคลาสสิกคือ
รวบรวมข้อกำหนด (requirements) → ออกแบบ (design) → พัฒนา (implementation) → ทดสอบ (testing) → ส่งมอบ/ติดตั้ง (deployment) → ดูแลรักษา (maintenance)
ภาพที่มักมากับ model นี้คือน้ำตกที่ไหลลงจากชั้นหนึ่งไปอีกชั้น ไม่มีทางไหลย้อนขึ้น เมื่อเซ็นอนุมัติข้อกำหนดแล้วก็ถือว่า “แช่แข็ง” ห้ามแตะ ทีมออกแบบรับช่วงต่อ เสร็จแล้วส่งต่อให้ทีมพัฒนา แล้วจึงส่งให้ทีมทดสอบเป็นด่านสุดท้าย งานถูกแบ่งตาม ชนิดของกิจกรรม ไม่ใช่ตาม คุณค่าที่ส่งมอบ ผลคือกว่าจะได้ซอฟต์แวร์ที่รันได้จริงให้ผู้ใช้เห็น ก็มักเป็นช่วงท้ายสุดของโครงการ
จุดที่หลายคนไม่รู้: บทความแรกที่วาดไดอะแกรม model นี้อย่างเป็นทางการ (ปี 1970 โดย Dr. Winston W. Royce) กลับเสนอมันในฐานะ ตัวอย่างของสิ่งที่ไม่ควรทำ Royce เขียนตรง ๆ ว่าแนวทางแบบผ่านครั้งเดียวจบ (single-pass) นั้น “เสี่ยงและเชื้อเชิญความล้มเหลว” แล้วใช้เนื้อหาที่เหลือของบทความอธิบายว่าต้องเพิ่ม iteration, feedback loop, การทำแต่ละขั้น “สองครั้ง” และการดึงลูกค้าเข้ามาร่วมตลอดทาง เขาไม่เคยใช้คำว่า “waterfall” ด้วยซ้ำ (คำนี้ปรากฏภายหลังราวปี 1976) แต่ประวัติศาสตร์กลับจดจำเขาผิด ในฐานะบิดาของ model ที่เขาเตือนให้ระวัง ต่อมามันถูกทำให้เป็นทางการยิ่งขึ้นผ่านมาตรฐานอย่าง DOD-STD-2167 ของกระทรวงกลาโหมสหรัฐฯ ในปี 1985 และแพร่หลายไปทั่วอุตสาหกรรม
สิ่งสำคัญที่ต้องแยกให้ออก: ปัญหาไม่ได้อยู่ที่การมีกิจกรรมอย่าง analysis, design หรือ testing — ทุกโครงการต้องทำสิ่งเหล่านี้อยู่แล้ว ปัญหาอยู่ที่การ บังคับให้มันเกิดเป็นเฟสก้อนใหญ่เรียงต่อกันครั้งเดียว ไหลทางเดียว และห้ามย้อนกลับ ในทางกลับกัน การพัฒนาแบบวนซ้ำก็ไม่ได้แปลว่า “ไม่มีแผน” หรือลุยเขียน code มั่ว ๆ แต่คือการทำกิจกรรมเดิมทั้งหมดนั่นแหละ เพียงแต่ย่อยให้เล็กลงและวนทำซ้ำหลายรอบ เพื่อให้ได้ feedback จากของจริงเร็วขึ้น เส้นแบ่งของแอนติ pattern นี้จึงอยู่ที่ความแข็งทื่อและความยาวของ loop ไม่ใช่ที่ตัวกิจกรรมเอง
ทำไมถึงดูน่าใช้
หัวข้อที่มีชื่อว่า “ทำไมถึงดูน่าใช้”- ให้ความรู้สึกคาดเดาได้และควบคุมได้ — เมื่อวาดแผนเป็นขั้นตอนเรียงกันชัดเจน ผู้บริหารสามารถชี้ได้ว่าตอนนี้โครงการอยู่ “เฟสไหน” ประเมิน timeline และงบประมาณล่วงหน้าได้เป็นตัวเลขสวยงาม ดูเหมือนทุกอย่างอยู่ในกำมือ
- เข้ากับสัญญาแบบ fixed-price — โครงการรับเหมาหรือโครงการภาครัฐมักต้องการเอกสาร spec ตายตัวเพื่อผูกมัดขอบเขตงานตั้งแต่วันแรก Waterfall จึงดูเหมาะเพราะมีเอกสารข้อกำหนดที่ “ปิด” ให้เซ็นได้
- เลียนแบบวิศวกรรมดั้งเดิม — คนจำนวนมากเทียบซอฟต์แวร์กับการสร้างตึกหรือสะพาน ที่ต้องมีพิมพ์เขียวครบก่อนลงมือเทคอนกรีต จึงรู้สึกว่าการ “ออกแบบให้จบก่อนสร้าง” คือวิธีที่มืออาชีพ โดยลืมไปว่าซอฟต์แวร์เปลี่ยนแปลงง่ายกว่าคอนกรีตมาก และความไม่แน่นอนของมันอยู่คนละระดับ
- แบ่งงานตามความเชี่ยวชาญได้ง่าย — องค์กรใหญ่ชอบโครงสร้างที่มีทีม analyst, ทีม designer, ทีม developer, ทีม QA แยกกันชัด ส่งงานต่อกันเป็นทอด ๆ ดูเป็นระเบียบและจัดคนได้ง่ายบนกระดาษ
- เอกสารครบให้ความอุ่นใจ — การมีเอกสารหนา ๆ ในแต่ละเฟสให้ความรู้สึกว่ามีหลักฐานความคืบหน้าที่จับต้องได้ แม้ว่าเอกสารเหล่านั้นจะยังไม่เคยถูกพิสูจน์ด้วยการรันจริงเลยก็ตาม
ทำไมถึงเป็นปัญหา
หัวข้อที่มีชื่อว่า “ทำไมถึงเป็นปัญหา”- ความเสี่ยงถูกเลื่อนไปโผล่ตอนท้ายสุด — ใน model นี้ การทดสอบและการ integration คือเฟสสุดท้าย ซึ่ง Royce ชี้ว่าเป็นครั้งแรกที่เรื่องเวลา หน่วยความจำ และพฤติกรรมจริงถูก “สัมผัส” แทนที่จะถูก “วิเคราะห์บนกระดาษ” ถ้าเจอปัญหาระดับสถาปัตยกรรมตอนนั้น การแก้ย่อมลามย้อนกลับไปทุกเฟสก่อนหน้า Martin Fowler เรียกสองเฟสท้ายนี้ว่าเป็นส่วนที่คาดเดาได้ยากที่สุดของโครงการ
- ยิ่งเจอ bug ช้า ยิ่งแพง — ตามที่ Wikipedia สรุปงานวิจัยไว้ ข้อบกพร่องที่ถูกพบในเฟสท้ายอาจมีต้นทุนแก้ไขสูงกว่าการพบตั้งแต่ต้นถึง 50–200 เท่า Waterfall เป็นโครงสร้างที่จงใจ (โดยไม่ตั้งใจ) เลื่อนการค้นพบข้อบกพร่องไปไว้ในจุดที่แพงที่สุด
- ข้อกำหนดที่สมบูรณ์ล่วงหน้าเป็นภาพลวง — ลูกค้ามักไม่สามารถบอกความต้องการทั้งหมดได้อย่างถูกต้องตั้งแต่วันแรก และการลงมือเขียน code จริงมักเปิดเผยเคสขอบและข้อจำกัดที่นักวิเคราะห์มองไม่เห็น การแยก analysis ออกจาก programming อย่างเด็ดขาดจึงเป็นไปไม่ได้ในทางปฏิบัติ Fowler ย้ำว่า “การส่งมอบ feature เพียงบางส่วนช่วยให้เห็นชัดว่าต้องทำอะไรต่อ” ได้ดีกว่าการนั่งเดาทั้งหมดล่วงหน้า
- ไม่มีซอฟต์แวร์ที่ใช้ได้จริงจนกว่าจะสาย — คุณค่าที่แท้จริง (ซอฟต์แวร์ที่รันได้) ปรากฏช้ามาก ผู้ใช้และผู้มีส่วนได้ส่วนเสียไม่ได้เห็นของจริงจนเกือบจบโครงการ ทำให้ feedback loop ยาวเป็นเดือนหรือเป็นปี ตรงข้ามกับหลักการ agile ที่ว่า “working software คือมาตรวัดความคืบหน้าหลัก”
- มองความคืบหน้าจริงไม่ออก — Fowler ชี้ว่ามัน “ง่ายเกินไปที่จะประกาศว่าเฟสหนึ่งเสร็จแล้ว” ทั้งที่ยังมีงานซ่อนอยู่มาก โครงการอาจดูเหมือนคืบไป 90% บนเอกสารมาหลายเดือน แล้วค้างอยู่ที่ 90% นั้นตลอดไปเมื่อถึงเฟส integration — อาการเดียวกับ Death by Planning
- ต้านทานการเปลี่ยนแปลงโดยธรรมชาติ — เมื่อทุกอย่างผูกกับเอกสารที่เซ็นอนุมัติแล้ว การเปลี่ยน requirement กลางทางกลายเป็นเรื่องราคาแพงและน่ากลัว ทั้งที่ในโลกจริงความต้องการทางธุรกิจเปลี่ยนตลอด agile จึงเลือก “ต้อนรับการเปลี่ยนแปลงแม้ในช่วงท้าย” แทนที่จะสู้กับมัน
- บ่มเพาะแอนติ pattern อื่นต่อเนื่อง — เฟส design ที่ต้องปิดให้สมบูรณ์ก่อนเขียน code คือแหล่งกำเนิดโดยตรงของ Big Design Up Front และความพยายามทำเอกสารให้ “ครบและถูก 100%” ก็ลากไปสู่ Analysis Paralysis ได้ง่าย ยิ่งเพิ่มคนเข้าไปเร่งโครงการที่ล่าช้าในกรอบนี้ ก็ยิ่งช้าลงตาม Brooks’s Law
ตัวอย่าง
หัวข้อที่มีชื่อว่า “ตัวอย่าง”ลองนึกถึงโครงการระบบ order-processing ที่วางแผนไว้ 12 เดือนแบบ Waterfall เต็มรูปแบบ
- เดือนที่ 1–2 ทีม business analyst เก็บ requirement จนได้เอกสาร spec หนาหลายร้อยหน้า ผู้มีส่วนได้ส่วนเสียเซ็นอนุมัติ ข้อกำหนดถูก “แช่แข็ง”
- เดือนที่ 3–5 ทีมสถาปนิกออกแบบทุก class ทุก interface ทุกตารางฐานข้อมูลบนกระดาษ ส่งมอบเอกสาร design ให้เซ็นอีกครั้ง
- เดือนที่ 6–9 ทีมพัฒนาเขียน code ตาม design โดยแทบไม่มีใครรันทั้งระบบพร้อมกัน แต่ละคนทำ module ของตัวเองตาม spec
- เดือนที่ 10 ถึงเวลา integration ครั้งแรก module ทั้งหมดถูกนำมาต่อกัน แล้วความจริงก็ปรากฏ: สมมติฐานเรื่อง throughput ผิด, กติกาส่วนลดที่ธุรกิจใช้เปลี่ยนไปตั้งแต่เดือนที่ 4, และ interface ระหว่างทีมไม่เข้ากันในหลายจุด
- เดือนที่ 11–12 ทีมเข้าสู่โหมด Death March เร่งแก้ย้อนกลับไปทุกเฟส ทำงานล่วงเวลา ตัด feature ทิ้ง เพื่อพยายามส่งมอบให้ทันเส้นตาย
หัวใจของปัญหาไม่ได้อยู่ที่ทีมทำงานไม่เก่ง แต่อยู่ที่ โครงสร้างกระบวนการเลื่อนช่วงเวลาแห่งการเรียนรู้ไปไว้ท้ายสุด ทุกความเสี่ยงถูกกองรวมไว้ในเดือนที่ 10 จุดเดียว
ถ้าโครงการเดียวกันนี้เดินแบบวนซ้ำ ทีมจะเลือก feature ที่สร้างคุณค่าสูงสุดหนึ่งอย่าง (เช่น “รับออร์เดอร์และตัดสต็อกได้จริง”) แล้วทำทะลุทุก layer ให้ผู้ใช้ลองใช้ภายในสองสัปดาห์แรก กติกาส่วนลดที่เปลี่ยนและปัญหา throughput จะถูกค้นพบตั้งแต่เดือนที่ 1–2 ในขณะที่ code ยังเล็กและแก้ได้ถูก แทนที่จะระเบิดพร้อมกันตอนเดือนที่ 10
เปรียบเทียบบนแกนที่สำคัญ
- ความเสี่ยงถูกเปิดเผยเมื่อไร — Waterfall: กระจุกตอนท้าย (integration/testing) · แบบวนซ้ำ: ทยอยเปิดเผยทุกรอบตั้งแต่ต้น
- ความยาวของ feedback loop — Waterfall: เป็นเดือนถึงเป็นปี · แบบวนซ้ำ: เป็นวันถึงเป็นสัปดาห์
- ต้นทุนของการเปลี่ยน requirement — Waterfall: สูงและเพิ่มขึ้นตามเวลา · แบบวนซ้ำ: คงที่และจัดการได้เพราะปรับทีละรอบ
- มาตรวัดความคืบหน้า — Waterfall: เอกสารที่เซ็นเสร็จในแต่ละเฟส · แบบวนซ้ำ: ซอฟต์แวร์ที่รันได้จริงและถูกใช้งาน
ทางแก้และการ refactor
หัวข้อที่มีชื่อว่า “ทางแก้และการ refactor”ทางแก้ไม่ใช่การเลิกวางแผนหรือเลิกออกแบบ แต่คือการ เปลี่ยนจากการแบ่งงานตามชนิดกิจกรรม มาเป็นการแบ่งงานตามคุณค่าที่ส่งมอบได้ แล้ววน loop สั้น ๆ ซ้ำ ๆ ให้เรียนรู้จากของจริงเร็วที่สุด นี่คือหัวใจของแนวทาง iterative/incremental และ agile — และน่าคิดว่ามันคือสิ่งที่ Royce เสนอไว้ตั้งแต่ปี 1970 อยู่แล้ว (ทำแต่ละขั้นซ้ำ, มี feedback, ดึงลูกค้าเข้ามาร่วม)
flowchart TD
W1[Requirements] --> W2[Design]
W2 --> W3[Implementation]
W3 --> W4[Testing]
W4 --> W5[Deployment]
W5 --> W6[bug ใหญ่โผล่ตอนท้าย ต้องรื้อย้อนหลัง]
I1[วางแผนรอบสั้น] --> I2[สร้าง feature ที่ใช้ได้จริง]
I2 --> I3[ทดสอบและรับ feedback จากผู้ใช้]
I3 --> I4[ปรับแผนตามของจริง]
I4 --> I1
หลักปฏิบัติที่ช่วยพลิกจาก Waterfall ไปสู่การพัฒนาแบบวนซ้ำ:
- ส่งมอบเป็น Vertical Slice บาง ๆ ที่ใช้งานได้จริง (Vertical Slices) — แทนที่จะทำทุก layer ให้ครบทีละ layer ให้เลือก feature เดียวแล้วทำทะลุตั้งแต่ UI จนถึงฐานข้อมูลให้ใช้ได้จริง ผู้ใช้จะได้ของไปลองและให้ feedback ตั้งแต่สัปดาห์แรก ๆ
- ผสาน analysis, design, code, test เข้าไว้ในทุกรอบ ไม่ใช่แยกเป็นเฟส การทดสอบต้องเกิดต่อเนื่อง ไม่ใช่ด่านสุดท้าย — ใช้ Test-Driven Development และ Behavior-Driven Development เพื่อเปลี่ยนข้อกำหนดให้เป็นตัวอย่างที่รันตรวจได้ทันที
- integrate ตลอดเวลา ไม่ใช่ครั้งเดียวตอนท้าย (Continuous Integration) — กำจัดความเสี่ยง big-bang integration ด้วยการรวม code และรัน build อัตโนมัติทุกวัน ปัญหาการเข้ากันของ module จะโผล่ทีละนิดในขณะที่ยังแก้ง่าย
- ตัดรอบให้สั้นด้วยการ timebox (Timeboxing) — กำหนดกรอบเวลาคงที่ต่อรอบ (เช่น 1–2 สัปดาห์) แล้วปรับ scope ให้พอดีกรอบ แทนที่จะยืดเวลาออกไปเรื่อย ๆ เพื่อทำ scope ที่ตายตัว
- ให้ทั้งทีมทำงานร่วมกันต่อเนื่อง ไม่ใช่ส่งงานเป็นทอด ๆ (Whole Team Activity) — ทลายกำแพงระหว่าง analyst, dev, QA และ business ให้อยู่ใน loop feedback เดียวกัน สอดคล้องกับหลักการ agile ที่ว่าธุรกิจและนักพัฒนาต้องทำงานด้วยกันทุกวัน
- เก็บ design ระดับสูงไว้ ปล่อยรายละเอียดให้ค่อย ๆ งอก — วางทิศทางสถาปัตยกรรมและเป้าหมายรวมไว้ (Architectural Agility) แต่ไม่ต้องล็อกทุกรายละเอียดล่วงหน้า ให้ design วิวัฒน์ตาม feedback จริงต่อเนื่อง
- สร้างระบบง่ายที่ใช้งานได้ก่อน แล้วค่อยวิวัฒน์ (Gall’s Law) — ระบบซับซ้อนที่ทำงานได้ดีมักวิวัฒน์มาจากระบบง่ายที่ทำงานได้ก่อนเสมอ ไม่ใช่ถูกออกแบบให้ครบสมบูรณ์ตั้งแต่ต้นแล้วเปิดสวิตช์ทีเดียว ซึ่งเป็นสมมติฐานที่ Waterfall ตั้งไว้โดยปริยาย
เป้าหมายไม่ใช่ “ไม่มีแผน” แต่คือ แผนที่ปรับได้ ที่ให้โอกาสระบบเรียนรู้และแก้ทางตั้งแต่เนิ่น ๆ ก่อนที่ความผิดพลาดจะกลายเป็นของแพง
ที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “ที่เกี่ยวข้อง”- Big Design Up Front
- Analysis Paralysis
- Death by Planning
- Vertical Slices
- Whole Team Activity
- Gall’s Law