Chapter 1. The Tar Pit
1.1 ผลิตภัณฑ์ระบบการเขียนโปรแกรม (programming systems product) ต้องใช้ความพยายามมากกว่าโปรแกรมส่วนประกอบที่เขียนขึ้นเพื่อใช้งานส่วนตัวประมาณเก้าเท่า ผมประเมินว่าการทำให้เป็นผลิตภัณฑ์ (productizing) จะเพิ่มภาระขึ้นสามเท่า และการออกแบบ การรวมระบบ และการทดสอบส่วนประกอบให้กลายเป็นระบบที่สอดคล้องกันจะเพิ่มภาระขึ้นอีกสามเท่า และต้นทุนทั้งสองส่วนนี้แทบจะเป็นอิสระต่อกัน
1.2 งานฝีมือของการเขียนโปรแกรม "ตอบสนองความปรารถนาในการสร้างสรรค์ที่ฝังลึกอยู่ในตัวเรา และสร้างความปีติยินดีในประสาทสัมผัสที่เรามีร่วมกับมนุษย์ทุกคน" โดยมอบความสุขห้าประการ:
- ความสุขในการสร้างสิ่งต่างๆ
- ความสุขในการสร้างสิ่งที่เป็นประโยชน์ต่อผู้อื่น
- ความหลงใหลในการประดิษฐ์วัตถุที่เหมือนปริศนาซึ่งประกอบด้วยชิ้นส่วนที่เคลื่อนไหวและเชื่อมโยงกัน
- ความสุขจากการได้เรียนรู้อยู่เสมอ จากงานที่ไม่ซ้ำเดิม
- ความปีติในการทำงานในสื่อกลางที่ปรับแต่งได้ง่าย—คือผลผลิตทางความคิดบริสุทธิ์—ทว่ามันมีตัวตน เคลื่อนไหว และทำงานในแบบที่วัตถุที่เป็นเพียงถ้อยคำทำไม่ได้
1.3 ในทำนองเดียวกัน งานฝีมือนี้ก็มีความทุกข์เฉพาะตัวแฝงอยู่:
-
การปรับตัวให้เข้ากับความต้องการความสมบูรณ์แบบเป็นส่วนที่ยากที่สุดของการเรียนรู้การเขียนโปรแกรม
-
ผู้อื่นเป็นคนกำหนดวัตถุประสงค์ และเราต้องพึ่งพาสิ่งต่างๆ (โดยเฉพาะโปรแกรม) ที่เราไม่สามารถควบคุมได้ อำนาจหน้าที่จึงไม่เท่ากับความรับผิดชอบ
-
เรื่องนี้ฟังดูแย่กว่าที่เป็นจริง: อำนาจหน้าที่ที่แท้จริงมาจากแรงขับเคลื่อนของความสำเร็จที่ทำได้จริง
-
ในงานสร้างสรรค์ใดๆ ย่อมมาพร้อมกับชั่วโมงการทำงานที่น่าเบื่อและยากลำบาก การเขียนโปรแกรมก็ไม่มีข้อยกเว้น
-
โครงการเขียนโปรแกรมมักจะลุล่วงช้าลงเรื่อยๆ เมื่อเข้าใกล้จุดจบ ทั้งที่คนเรามักจะคาดหวังว่ามันควรจะเร็วขึ้นเมื่อใกล้จะเสร็จ
-
ผลิตภัณฑ์ของเรามักจะถูกคุกคามด้วยความล้าสมัยก่อนที่มันจะเสร็จสมบูรณ์ "เสือตัวจริง" ไม่มีวันสู้ "เสือบนกระดาษ" ได้เลย เว้นแต่ความต้องการใช้งานจริงจะเป็นตัวตัดสิน
Chapter 2. The Mythical Man-Month
2.1 โครงการเขียนโปรแกรมจำนวนมากผิดพลาดเพราะ "ขาดแคลนเวลาตามปฏิทิน" มากกว่าสาเหตุอื่นๆ ทั้งหมดรวมกัน
2.2 การทำอาหารที่ดีต้องใช้เวลา งานบางอย่างไม่สามารถเร่งได้โดยไม่ทำให้ผลลัพธ์พังทลาย
2.3 นักเขียนโปรแกรมทุกคนคือพวกมองโลกในแง่ดี: "ทุกอย่างจะผ่านไปด้วยดี"
2.4 เพราะนักเขียนโปรแกรมสร้างสิ่งต่างๆ จากความคิดบริสุทธิ์ เราจึงคาดหวังว่าจะเจออุปสรรคเพียงเล็กน้อยในการนำไปใช้งาน
2.5 แต่ความคิดของเราเองนั่นแหละที่ผิดพลาด เราจึงมีบั๊ก
2.6 เทคนิคการประมานการของเรา ซึ่งสร้างขึ้นจากการบัญชีต้นทุน มักสับสนระหว่าง "ความพยายาม" (effort) และ "ความก้าวหน้า" (progress) เดือน-คน (man-month) คือตำนานที่ผิดพลาดและอันตราย เพราะมันบอกเป็นนัยว่าคนและเดือนสามารถทดแทนกันได้
2.7 การแบ่งงานท่ามกลางคนหลายคนทำให้เกิดภาระการสื่อสารเพิ่มเติม—ทั้งการฝึกอบรมและการสื่อสารระหว่างกัน
2.8 กฎพื้นฐานของผมคือ ใช้ 1/3 ของกำหนดการสำหรับการออกแบบ, 1/6 สำหรับการเขียนโค้ด, 1/4 สำหรับการทดสอบส่วนประกอบ และ 1/4 สำหรับการทดสอบระบบ
2.9 ในฐานะสาขาวิชาหนึ่ง เราขาดแคลนข้อมูลในการประมานการ
2.10 เพราะเราไม่แน่ใจเกี่ยวกับการประมานการกำหนดการของเรา เราจึงมักขาดความกล้าหาญที่จะยืนหยัดปกป้องมันต่อแรงกดดันจากฝ่ายบริหารและลูกค้า
2.11 กฎของบรูคส์ (Brooks's Law): การเพิ่มกำลังคนเข้าไปในโครงการซอฟต์แวร์ที่ล่าช้า จะยิ่งทำให้มันล่าช้ามากขึ้น
2.12 การเพิ่มคนเข้าไปในโครงการซอฟต์แวร์จะเพิ่มความพยายามทั้งหมดที่จำเป็นในสามทาง ได้แก่: งานและการรบกวนจากการแบ่งส่วนงานใหม่เอง, การฝึกอบรมคนใหม่ และการสื่อสารระหว่างกันที่เพิ่มขึ้น
Chapter 3. The Surgical Team
3.1 นักเขียนโปรแกรมมืออาชีพที่เก่งมาก มีผลิตภาพสูงกว่านักเขียนโปรแกรมที่ด้อยฝีมือถึงสิบเท่า เมื่อผ่านการฝึกอบรมและมีประสบการณ์สองปีในระดับเดียวกัน (Sackman, Grant, และ Erickson)
3.2 ข้อมูลของ Sackman, Grant และ Erickson ไม่พบความสัมพันธ์ใดๆ ระหว่างประสบการณ์และประสิทธิภาพการทำงาน ผมสงสัยในความเป็นสากลของผลลัพธ์นี้
3.3 ทีมขนาดเล็กที่เฉียบคมนั้นดีที่สุด—คือใช้จำนวนคนให้น้อยที่สุดเท่าที่จะเป็นไปได้
3.4 ทีมที่มีสองคน โดยมีหัวหน้าหนึ่งคน มักเป็นการใช้สติปัญญาที่เกิดประโยชน์สูงสุด [สังเกตแผนการของพระเจ้าเรื่องการแต่งงาน]
3.5 ทีมขนาดเล็กที่เฉียบคมนั้นช้าเกินไปสำหรับระบบที่ใหญ่จริงๆ
3.6 ประสบการณ์ส่วนใหญ่กับระบบขนาดใหญ่มากแสดงให้เห็นว่า วิธีการขยายขนาดแบบใช้กำลังเข้าว่า (brute-force approach) นั้นมีต้นทุนสูง ช้า ไร้ประสิทธิภาพ และสร้างระบบที่ขาดความสอดคล้องทางแนวคิด
3.7 องค์กรแบบทีมผ่าตัดโดยมีหัวหน้านักเขียนโปรแกรม มอบวิธีการที่จะได้ความสอดคล้องของผลิตภัณฑ์จากจิตใจเพียงไม่กี่ดวง และได้ผลิตภาพรวมจากผู้ช่วยจำนวนมาก โดยลดภาระการสื่อสารลงอย่างมหาศาล
Chapter 4. Aristocracy, Democracy, and System Design
4.1 "ความสอดคล้องทางแนวคิด (conceptual integrity) คือข้อพิจารณาที่สำคัญที่สุดในการออกแบบระบบ"
4.2 "อัตราส่วนของฟังก์ชันต่อความซับซ้อนเชิงแนวคิด คือบททดสอบสูงสุดของการออกแบบระบบ" ไม่ใช่แค่ความรุ่มรวยของฟังก์ชันเท่านั้น [อัตราส่วนนี้คือมาตรวัดความง่ายในการใช้งาน ซึ่งใช้ได้ผลทั้งกับการใช้งานที่ง่ายและที่ยาก]
4.3 เพื่อบรรลุความสอดคล้องทางแนวคิด งานออกแบบต้องมาจากจิตใจเพียงดวงเดียวหรือกลุ่มคนกลุ่มเล็กๆ ที่เห็นพ้องต้องกัน
4.4 "การแยกความพยายามด้านสถาปัตยกรรมออกจากการนำไปใช้งาน เป็นวิธีที่ทรงพลังมากในการบรรลุการบูรณาการทางแนวคิดในโครงการขนาดใหญ่" [รวมถึงโครงการขนาดเล็กด้วย]
4.5 "หากระบบต้องมีความสอดคล้องทางแนวคิด ใครบางคนต้องควบคุมแนวคิดเหล่านั้น นั่นคือความเป็นชนชั้นนำ (aristocracy) ที่ไม่จำเป็นต้องขอโทษใคร"
4.6 ระเบียบวินัยนั้นดีต่อศิลปะ การจัดเตรียมสถาปัตยกรรมจากภายนอกช่วยส่งเสริม ไม่ใช่ตีกรอบ รูปแบบการสร้างสรรค์ของกลุ่มผู้นำไปใช้งาน
4.7 ระบบที่สอดคล้องกันทางแนวคิดจะสร้างและทดสอบได้เร็วกว่า
4.8 งานสถาปัตยกรรมซอฟต์แวร์ การนำไปใช้งาน และการทำให้เป็นจริงส่วนใหญ่สามารถดำเนินไปคู่ขนานกันได้ [งานออกแบบฮาร์ดแวร์และซอฟต์แวร์ก็สามารถดำเนินไปคู่ขนานกันได้เช่นกัน]
Chapter 5. The Second-System Effect
5.1 การสื่อสารที่เริ่มเร็วและทำอย่างต่อเนื่องสามารถให้ข้อมูลด้านต้นทุนที่ดีแก่สถาปนิก และสร้างความมั่นใจในงานออกแบบให้แก่ผู้สร้าง โดยไม่ทำให้การแบ่งความรับผิดชอบที่ชัดเจนนั้นเลือนหายไป 5.2 วิธีการที่สถาปนิกจะส่งอิทธิพลต่อการนำไปใช้งานได้อย่างประสบความสำเร็จ:
- จดจำไว้ว่าผู้สร้างมีความรับผิดชอบในการสร้างสรรค์เพื่อนำไปใช้งาน สถาปนิกทำหน้าที่เพียงแนะนำเท่านั้น
- เตรียมพร้อมเสมอที่จะเสนอวิธีนำสิ่งที่คุณกำหนดไปสร้างจริง และเตรียมพร้อมที่จะยอมรับวิธีอื่นๆ ที่ดีเท่ากัน
- จัดการคำแนะนำเหล่านั้นอย่างเงียบๆ และเป็นส่วนตัว
- พร้อมที่จะสละชื่อเสียงจากข้อเสนอแนะในการปรับปรุง
-
รับฟังข้อเสนอแนะของผู้สร้างในการปรับปรุงสถาปัตยกรรม
5.3 ระบบที่สองคือระบบที่อันตรายที่สุดเท่าที่คนคนหนึ่งจะเคยออกแบบ แนวโน้มทั่วไปคือการออกแบบมันให้ "มากเกินไป" (
over-design) 5.4 OS/360 เป็นตัวอย่างที่ดีของผลกระทบจากระบบที่สอง [Windows NT ดูเหมือนจะเป็นตัวอย่างในทศวรรษ 1990] 5.5 การกำหนดมูลค่าล่วงหน้าในรูปของไบต์และไมโครวินาทีให้กับแต่ละฟังก์ชันคือระเบียบวินัยที่คุ้มค่า
Chapter 6. Passing the Word
6.1 แม้ทีมออกแบบจะมีขนาดใหญ่ แต่ผลลัพธ์จะต้องถูกถ่ายทอดออกมาเป็นลายลักษณ์อักษรโดยคนเพียงหนึ่งหรือสองคน เพื่อให้การตัดสินใจย่อยๆ มีความสอดคล้องกัน
6.2 สิ่งสำคัญคือต้องระบุส่วนของสถาปัตยกรรมที่ "ไม่ได้ถูกกำหนดไว้" ให้ชัดเจนพอๆ กับส่วนที่ถูกกำหนดไว้
6.3 เราต้องการทั้ง "คำจำกัดความแบบเป็นทางการ" ของงานออกแบบเพื่อความแม่นยำ และ "คำจำกัดความแบบร้อยแก้ว" เพื่อความเข้าใจง่าย
6.4 จะต้องมีคำจำกัดความแบบใดแบบหนึ่ง (เป็นทางการหรือร้อยแก้ว) เป็น "มาตรฐาน" และอีกแบบหนึ่งเป็น "ส่วนอนุมาน" โดยคำจำกัดความแบบใดก็สามารถทำหน้าที่ในบทบาทใดก็ได้
6.5 การนำไปใช้งาน รวมถึงโปรแกรมจำลอง สามารถทำหน้าที่เป็นคำจำกัดความทางสถาปัตยกรรมได้ แต่การใช้งานเช่นนั้นมีข้อเสียที่น่ากลัวหลายประการ
6.6 การรวมเข้าด้วยกันโดยตรง (direct incorporation) เป็นเทคนิคที่สะอาดมากในการบังคับใช้มาตรฐานทางสถาปัตยกรรมในซอฟต์แวร์ [ในฮาร์ดแวร์ก็เช่นกัน—ลองพิจารณาอินเทอร์เฟซ Mac WIMP ที่สร้างไว้ใน ROM]
6.7 คำจำกัดความทางสถาปัตยกรรม "จะสะอาดขึ้นและระเบียบวินัยทางสถาปัตยกรรมจะเข้มงวดขึ้น หากมีการสร้างการนำไปใช้งานอย่างน้อยสองรูปแบบตั้งแต่เริ่มต้น"
6.8 สิ่งสำคัญคือต้องอนุญาตให้สถาปนิกตอบคำถามและตีความทางโทรศัพท์ได้ แต่จำเป็นอย่างยิ่งที่จะต้องบันทึกและเผยแพร่การตีความเหล่านั้น [ปัจจุบันอีเมลกลายเป็นสื่อกลางที่ได้รับความนิยมมากกว่า]
6.9 "เพื่อนที่ดีที่สุดของผู้จัดการโครงการคือคู่ปรับประจำวันของเขา ซึ่งก็คือองค์กรทดสอบผลิตภัณฑ์ที่เป็นอิสระ"
Chapter 7. Why Did the Tower of Babel Fail?
7.1 โครงการหอคอยบาเบลล้มเหลวเพราะการขาดการสื่อสารและผลที่ตามมาคือ องค์กร
การสื่อสาร (Communication)
7.2 "หายนะของกำหนดการ ความไม่เข้ากันของคุณสมบัติ และบั๊กของระบบ ทั้งหมดเกิดขึ้นเพราะมือซ้ายไม่รู้ว่ามือขวาทำอะไร" ทีมต่างๆ มีสมมติฐานที่ค่อยๆ แยกห่างออกจากกัน 7.3 ทีมควรสื่อสารกันในหลายวิธีที่สุดเท่าที่จะทำได้: ทั้งแบบไม่เป็นทางการ, โดยการประชุมโครงการตามปกติพร้อมการสรุปข้อมูลทางเทคนิค และผ่านสมุดงานโครงการที่เป็นทางการร่วมกัน [และทางอีเมล]
สมุดงานโครงการ (Project Workbook)
7.4 สมุดงานโครงการ "ไม่ได้เป็นเพียงเอกสารที่แยกต่างหาก แต่เป็นโครงสร้างที่ถูกกำหนดให้กับเอกสารที่โครงการจะผลิตขึ้นอยู่แล้ว" 7.5 "เอกสารทั้งหมดของโครงการจำเป็นต้องเป็นส่วนหนึ่งของโครงสร้าง [สมุดงาน] นี้" 7.6 โครงสร้างสมุดงานต้องได้รับการออกแบบอย่างระมัดระวังและทำตั้งแต่เนิ่นๆ 7.7 การจัดโครงสร้างเอกสารประกอบที่ดำเนินอยู่อย่างเหมาะสมตั้งแต่เริ่มต้น จะช่วย "หล่อหลอมงานเขียนในภายหลังให้เป็นส่วนๆ ที่ลงตัวกับโครงสร้างนั้น" และจะช่วยปรับปรุงคู่มือของผลิตภัณฑ์ให้ดีขึ้น 7.8 "สมาชิกในทีมแต่ละคนควรเห็นเนื้อหา [ในสมุดงาน] ทั้งหมด" [ตอนนี้ผมจะบอกว่า สมาชิกแต่ละคนควรจะ "สามารถ" เข้าถึงเพื่อดูได้ทั้งหมด ซึ่งหน้าเว็บ World-Wide Web ก็เพียงพอแล้ว] 7.9 การอัปเดตให้ทันเวลามีความสำคัญอย่างยิ่ง 7.10 ผู้ใช้จำเป็นต้องได้รับการดึงดูดความสนใจเป็นพิเศษไปยังส่วนที่เปลี่ยนแปลงนับจากการอ่านครั้งล่าสุด พร้อมหมายเหตุถึงความสำคัญของการเปลี่ยนแปลงนั้น 7.11 สมุดงานของโครงการ OS/360 เริ่มต้นด้วยกระดาษและเปลี่ยนไปใช้ไมโครฟิช 7.12 ในปัจจุบัน [แม้จะเป็นปี 1975] สมุดบันทึกอิเล็กทรอนิกส์ที่ใช้ร่วมกันเป็นกลไกที่ดีกว่า ถูกกว่า และเรียบง่ายกว่ามากในการบรรลุเป้าหมายทั้งหมดนี้
7.13 เรายังคงต้องทำเครื่องหมายในข้อความด้วย [สิ่งที่เทียบเท่ากับ] แถบแสดงการเปลี่ยนแปลงและวันที่แก้ไข และยังคงต้องมีบทสรุปการเปลี่ยนแปลงอิเล็กทรอนิกส์แบบเข้าก่อนออกหลัง (LIFO)
7.14 Parnas โต้แย้งอย่างหนักแน่นว่าเป้าหมายที่ให้ทุกคนเห็นทุกอย่างนั้นผิดโดยสิ้นเชิง ชิ้นส่วนควรถูกห่อหุ้ม (encapsulated) ไว้เพื่อไม่ให้ใครจำเป็นต้องหรือได้รับอนุญาตให้เห็นภายในของชิ้นส่วนอื่นๆ นอกจากของตนเอง แต่ควรเห็นเพียงแค่อินเทอร์เฟซเท่านั้น
7.15 ข้อเสนอของ Parnas คือสูตรสำเร็จของหายนะ [ผมได้รับความกระจ่างจาก Parnas และเปลี่ยนใจไปอย่างสิ้นเชิงแล้ว]
องค์กร (Organization)
7.16 จุดประสงค์ขององค์กรคือการลดปริมาณการสื่อสารและการประสานงานที่จำเป็น
7.17 องค์กรรวบรวมการแบ่งงานและความเชี่ยวชาญตามหน้าที่ เพื่อหลีกเลี่ยงความจำเป็นในการสื่อสาร
7.18 องค์กรแบบต้นไม้ตามแบบดั้งเดิมสะท้อนถึงหลักการโครงสร้างอำนาจหน้าที่ที่ว่า คนเราไม่สามารถรับใช้เจ้านายสองคนได้
7.19 โครงสร้างการสื่อสารในองค์กรเป็นแบบโครงข่าย (network) ไม่ใช่แบบต้นไม้ ดังนั้นกลไกองค์กรพิเศษทุกประเภท ("เส้นประ") จึงต้องถูกคิดค้นขึ้นเพื่อเอาชนะข้อบกพร่องด้านการสื่อสารขององค์กรที่มีโครงสร้างแบบต้นไม้
7.20 ทุกโครงการย่อยมีบทบาทความเป็นผู้นำสองตำแหน่งที่ต้องเติมเต็ม คือ "ผู้ผลิต" (producer) และ "ผู้อำนวยการด้านเทคนิค" หรือสถาปนิก หน้าที่ของทั้งสองบทบาทนี้แตกต่างกันอย่างชัดเจนและต้องการพรสวรรค์ที่แตกต่างกัน
7.21 ความสัมพันธ์แบบใดแบบหนึ่งในสามรูปแบบนี้ระหว่างสองบทบาทสามารถมีประสิทธิภาพได้:
- ผู้ผลิตและผู้อำนวยการเป็นคนเดียวกัน
- ผู้ผลิตเป็นหัวหน้า และผู้อำนวยการเป็นมือขวาของผู้ผลิต
- ผู้อำนวยการเป็นหัวหน้า และผู้ผลิตเป็นมือขวาของผู้อำนวยการ
Chapter 8. Calling the Shot
8.1 เราไม่สามารถประมานการความพยายามหรือกำหนดการทั้งหมดของโครงการเขียนโปรแกรมได้อย่างแม่นยำ เพียงแค่การประมานการเวลาเขียนโค้ดแล้วคูณด้วยปัจจัยต่างๆ สำหรับส่วนอื่นของงาน 8.2 ข้อมูลสำหรับการสร้างระบบขนาดเล็กที่แยกส่วนกัน ไม่สามารถนำมาใช้กับโครงการระบบการเขียนโปรแกรมได้ 8.3 ความพยายามในการเขียนโปรแกรมเพิ่มขึ้นตามเลขยกกำลังของขนาดโปรแกรม 8.4 การศึกษาบางชิ้นที่ตีพิมพ์แสดงให้เห็นว่าเลขยกกำลังอยู่ที่ประมาณ 1.5 [ข้อมูลของ Boehm ไม่เห็นด้วยกับเรื่องนี้เลย โดยตัวเลขจะอยู่ที่ 1.05 ถึง 1.2] 8.5 ข้อมูล ICL ของ Portman แสดงให้เห็นว่านักเขียนโปรแกรมเต็มเวลาใช้เวลาเพียงประมาณ 50 เปอร์เซ็นต์ไปกับการเขียนโปรแกรมและแก้ไขข้อผิดพลาด เมื่อเทียบกับงานประเภทภายนอกอื่นๆ 8.6 ข้อมูล IBM ของ Aron แสดงให้เห็นว่าผลิตภาพแปรผันตั้งแต่ 1.5 K บรรทัดโค้ด (KLOC) ต่อคน-ปี ไปจนถึง 10 KLOC ต่อคน-ปี โดยเป็นฟังก์ชันของจำนวนการปฏิสัมพันธ์ระหว่างส่วนประกอบต่างๆ ของระบบ 8.7 ข้อมูล Bell Labs ของ Harr แสดงให้เห็นผลิตภาพในงานประเภทระบบปฏิบัติการอยู่ที่ประมาณ 0.6 KLOC ต่อคน-ปี และในงานประเภทคอมไพเลอร์อยู่ที่ประมาณ 2.2 KLOC ต่อคน-ปี สำหรับผลิตภัณฑ์ที่เสร็จสมบูรณ์ 8.8 ข้อมูล OS/360 ของ Brooks สอดคล้องกับของ Harr: คือ 0.6-0.8 KLOC ต่อคน-ปี สำหรับระบบปฏิบัติการ และ 2-3 KLOC ต่อคน-ปี สำหรับคอมไพเลอร์ 8.9 ข้อมูลโครงการ MULTICS ของ MIT โดย Corbató แสดงผลิตภาพที่ 1.2 KLOC ต่อคน-ปี สำหรับงานที่ผสมกันระหว่างระบบปฏิบัติการและคอมไพเลอร์ แต่ตัวเลขนี้เป็นบรรทัดโค้ดภาษา PL/I ในขณะที่ข้อมูลอื่นๆ ทั้งหมดเป็นบรรทัดโค้ดภาษาแอสเซมบลี! 8.10 ผลิตภาพดูเหมือนจะคงที่ในแง่ของจำนวนคำสั่งพื้นฐาน 8.11 ผลิตภาพการเขียนโปรแกรมอาจเพิ่มขึ้นได้มากถึงห้าเท่า เมื่อมีการใช้ภาษาระดับสูงที่เหมาะสม
Chapter 9. Ten Pounds in a Five-Pound Sack
9.1 นอกจากเวลารันแล้ว พื้นที่หน่วยความจำที่โปรแกรมครอบครองก็เป็นต้นทุนหลัก ข้อนี้เป็นจริงอย่างยิ่งสำหรับระบบปฏิบัติการ ซึ่งเนื้อหาส่วนใหญ่ต้องฝังตัวอยู่ตลอดเวลา
9.2 ถึงอย่างนั้น เงินที่จ่ายไปกับหน่วยความจำเพื่อให้โปรแกรมฝังตัวอยู่อาจมอบคุณค่าทางหน้าที่การทำงานที่คุ้มค่ามากต่อหนึ่งดอลลาร์ ดีกว่าการลงทุนในส่วนประกอบอื่นๆ ของการกำหนดค่าระบบ ขนาดของโปรแกรมไม่ใช่สิ่งเลวร้าย แต่ขนาดที่ไม่จำเป็นต่างหากที่แย่
9.3 ผู้สร้างซอฟต์แวร์ต้องกำหนดเป้าหมายขนาด ควบคุมขนาด และคิดค้นเทคนิคการลดขนาด เช่นเดียวกับที่ผู้สร้างฮาร์ดแวร์ทำกับชิ้นส่วนต่างๆ
9.4 งบประมาณขนาดต้องมีความชัดเจน ไม่เพียงแค่ขนาดในหน่วยความจำหลักเท่านั้น แต่ยังรวมถึงการเข้าถึงดิสก์ที่เกิดจากการดึงโปรแกรมเข้ามาใช้งานด้วย
9.5 งบประมาณขนาดต้องผูกติดกับการมอบหมายหน้าที่การทำงาน จงนิยามให้แน่ชัดว่าโมดูลต้องทำอะไร เมื่อคุณระบุว่ามันต้องมีขนาดเท่าใด
9.6 ในทีมขนาดใหญ่ ทีมย่อยมีแนวโน้มที่จะปรับปรุงส่วนของตนเองให้ดีที่สุด (suboptimize) เพื่อให้บรรลุเป้าหมายของตนเอง แทนที่จะคำนึงถึงผลกระทบโดยรวมต่อผู้ใช้ การขาดความเข้าใจในทิศทางนี้คืออันตรายหลักของโครงการขนาดใหญ่
9.7 ตลอดเวลาของการนำไปใช้งาน สถาปนิกของระบบต้องคอยเฝ้าระวังอย่างต่อเนื่องเพื่อรักษาความสอดคล้องของระบบไว้
9.8 การปลูกฝังทัศนคติที่เน้นระบบโดยรวมและเน้นผู้ใช้เป็นศูนย์กลาง อาจเป็นหน้าที่ที่สำคัญที่สุดของผู้จัดการฝ่ายเขียนโปรแกรม
9.9 การตัดสินใจเชิงนโยบายในระยะแรกคือการกำหนดว่าทางเลือกของผู้ใช้ควรจะละเอียดเพียงใด เนื่องจากการรวมกลุ่มตัวเลือกเข้าด้วยกันจะช่วยประหยัดหน่วยความจำ [และมักจะลดต้นทุนทางการตลาดด้วย]
9.10 ขนาดของพื้นที่ชั่วคราว (transient area) และปริมาณโปรแกรมต่อการดึงข้อมูลจากดิสก์หนึ่งครั้ง คือการตัดสินใจที่สำคัญยิ่ง เพราะประสิทธิภาพจะเป็นฟังก์ชันที่เพิ่มขึ้นมากกว่าสัดส่วนที่เป็นเส้นตรงตามขนาดนั้น [การตัดสินใจนี้ล้าสมัยไปแล้ว เริ่มจากการมีหน่วยความจำเสมือน และต่อมาด้วยหน่วยความจำจริงที่มีราคาถูก ปัจจุบันผู้ใช้มักซื้อหน่วยความจำจริงมากพอที่จะเก็บโค้ดทั้งหมดของแอปพลิเคชันหลักๆ ไว้ได้]
9.11 เพื่อให้การแลกเปลี่ยนระหว่างพื้นที่และเวลา (space-time tradeoffs) เป็นไปได้ด้วยดี ทีมจำเป็นต้องได้รับการฝึกฝนในเทคนิคการเขียนโปรแกรมที่เฉพาะเจาะจงสำหรับภาษาหรือเครื่องจักรนั้นๆ โดยเฉพาะเครื่องรุ่นใหม่
9.12 การเขียนโปรแกรมมีเทคโนโลยีของมัน และทุกโครงการต้องการคลังส่วนประกอบที่เป็นมาตรฐาน
9.13 คลังโปรแกรมควรมีส่วนประกอบแต่ละอย่างในสองเวอร์ชัน คือแบบเน้นความเร็ว และแบบบีบอัดขนาด [เรื่องนี้ดูจะล้าสมัยไปแล้วในปัจจุบัน]
9.14 โปรแกรมที่กระชับ เรียบง่าย และรวดเร็ว เกือบทั้งหมดเป็นผลมาจากความก้าวหน้าในระดับกลยุทธ์ มากกว่าความชาญฉลาดในระดับยุทธวิธี
9.15 บ่อยครั้งที่ความก้าวหน้าดังกล่าวจะเป็นอัลกอริทึมใหม่
9.16 แต่บ่อยครั้งยิ่งกว่า ความก้าวหน้าจะมาจากการออกแบบการแสดงแทนข้อมูลหรือตารางใหม่ การแสดงแทนข้อมูลคือหัวใจสำคัญของการเขียนโปรแกรม
Chapter 10. The Documentary Hypothesis
10.1 "สมมติฐานคือ: ท่ามกลางกองกระดาษจำนวนมหาศาล เอกสารจำนวนน้อยนิดกลายเป็นแกนหมุนที่สำคัญซึ่งการบริหารจัดการทุกโครงการต้องพึ่งพา สิ่งเหล่านี้คือเครื่องมือส่วนตัวที่สำคัญที่สุดของผู้จัดการ" 10.2 สำหรับโครงการพัฒนาคอมพิวเตอร์ เอกสารสำคัญคือ: วัตถุประสงค์, คู่มือ, กำหนดการ, งบประมาณ, แผนผังองค์กร, การจัดสรรพื้นที่ทำงาน และการประมานการ การพยากรณ์ และราคาของตัวเครื่อง 10.3 สำหรับแผนกวิชาในมหาวิทยาลัย เอกสารสำคัญก็คล้ายคลึงกัน ได้แก่: วัตถุประสงค์, ข้อกำหนดการรับปริญญา, คำอธิบายรายวิชา, ข้อเสนอการวิจัย, ตารางเรียนและแผนการสอน, งบประมาณ, การจัดสรรพื้นที่ทำงาน และการมอบหมายงานให้เจ้าหน้าที่และผู้ช่วยวิจัย 10.4 สำหรับโครงการซอฟต์แวร์ ความต้องการก็เหมือนกัน: วัตถุประสงค์, คู่มือผู้ใช้, เอกสารประกอบภายใน, กำหนดการ, งบประมาณ, แผนผังองค์กร และการจัดสรรพื้นที่ทำงาน 10.5 ดังนั้น แม้ในโครงการขนาดเล็ก ผู้จัดการควรเริ่มจัดทำชุดเอกสารเหล่านี้ให้เป็นทางการตั้งแต่เริ่มต้น 10.6 การเตรียมเอกสารแต่ละฉบับในชุดเล็กๆ นี้ช่วยรวบรวมความคิดและทำให้การอภิปรายชัดเจนขึ้น การเขียนต้องใช้การตัดสินใจย่อยๆ นับร้อยครั้ง และการมีอยู่ของการตัดสินใจเหล่านี้เองที่แยกแยะนโยบายที่ชัดเจนและแม่นยำออกจากนโยบายที่คลุมเครือ 10.7 การบำรุงรักษาเอกสารสำคัญแต่ละฉบับช่วยให้มีกลไกการเฝ้าสังเกตสถานะและระบบเตือนภัย 10.8 ตัวเอกสารแต่ละฉบับเองทำหน้าที่เป็นรายการตรวจสอบและฐานข้อมูล 10.9 งานพื้นฐานของผู้จัดการโครงการคือการทำให้ทุกคนมุ่งหน้าไปในทิศทางเดียวกัน 10.10 งานประจำวันที่สำคัญที่สุดของผู้จัดการโครงการคือการสื่อสาร ไม่ใช่การตัดสินใจ โดยเอกสารจะทำหน้าที่สื่อสารแผนงานและการตัดสินใจไปยังทั้งทีม 10.11 เวลาเพียงส่วนน้อยของผู้จัดการโครงการทางเทคนิค—อาจจะ 20 เปอร์เซ็นต์—เท่านั้นที่ใช้ไปกับงานที่เขาต้องการข้อมูลจากภายนอกสมองของเขาเอง
10.12 ด้วยเหตุผลนี้ แนวคิดทางการตลาดที่กล่าวถึง "ระบบข้อมูลการบริหารจัดการแบบเบ็ดเสร็จ" เพื่อสนับสนุนผู้บริหาร จึงไม่ได้ตั้งอยู่บนแบบจำลองพฤติกรรมที่แท้จริงของผู้บริหาร
Chapter 11. Plan to Throw One Away
11.1 วิศวกรเคมีเรียนรู้ที่จะไม่นำกระบวนการจากห้องแล็บไปสู่โรงงานผลิตในขั้นตอนเดียว แต่จะสร้างโรงงานต้นแบบ (pilot plant) เพื่อเก็บเกี่ยวประสบการณ์ในการขยายขนาดการผลิตและการทำงานในสภาพแวดล้อมที่ไม่มีการป้องกัน
11.2 ขั้นตอนระหว่างกลางนี้จำเป็นพอๆ กันสำหรับผลิตภัณฑ์โปรแกรม แต่วิศวกรซอฟต์แวร์ยังไม่ทำการทดสอบระบบต้นแบบในภาคสนามเป็นปกติก่อนจะเริ่มส่งมอบผลิตภัณฑ์จริง [ปัจจุบันเรื่องนี้กลายเป็นแนวปฏิบัติทั่วไปผ่านเวอร์ชันเบต้า (beta version) แต่นั่นไม่เหมือนกับตัวต้นแบบที่มีฟังก์ชันจำกัดอย่างเวอร์ชันอัลฟ่า (alpha version) ซึ่งผมสนับสนุนให้ทำเช่นกัน]
11.3 สำหรับโครงการส่วนใหญ่ ระบบแรกที่สร้างขึ้นนั้นแทบจะใช้งานไม่ได้เลย: อาจจะช้าเกินไป ใหญ่เกินไป ใช้งานยากเกินไป หรือเป็นทั้งสามอย่าง
11.4 การทิ้งและออกแบบใหม่จะเกิดขึ้นแน่นอน ไม่ว่าจะทำรวดเดียวหรือทำไปทีละชิ้น
11.5 การส่งมอบระบบแรกซึ่งเป็นของที่จะต้องทิ้งให้แก่ผู้ใช้ อาจเป็นการซื้อเวลา แต่มันทำได้โดยแลกมาด้วยความทุกข์ทรมานของผู้ใช้ ความว้าวุ่นใจของผู้สร้างที่ต้องคอยสนับสนุนมันในขณะที่ทำการออกแบบใหม่ และชื่อเสียของผลิตภัณฑ์ที่ยากจะลบล้างได้
11.6 ดังนั้น จงวางแผนที่จะทิ้งมันไปหนึ่งชิ้น เพราะอย่างไรเสียคุณก็ต้องทำเช่นนั้นอยู่ดี
11.7 "นักเขียนโปรแกรมส่งมอบความพึงพอใจต่อความต้องการของผู้ใช้ มากกว่าจะเป็นผลิตภัณฑ์ที่จับต้องได้" (Cosgrove)
11.8 ทั้งความต้องการที่แท้จริงและการรับรู้ถึงความต้องการนั้นของผู้ใช้จะเปลี่ยนไปเมื่อโปรแกรมถูกสร้าง ทดสอบ และใช้งาน
11.9 ความอ่อนตัว (tractability) และความมองไม่เห็น (invisibility) ของผลิตภัณฑ์ซอฟต์แวร์ ทำให้ผู้สร้างต้องเผชิญกับการเปลี่ยนแปลงข้อกำหนดอย่างต่อเนื่อง (มากกว่างานวิศวกรรมอื่นๆ)
11.10 การเปลี่ยนแปลงบางประการในวัตถุประสงค์ (และในกลยุทธ์การพัฒนา) เป็นสิ่งที่หลีกเลี่ยงไม่ได้ และเป็นการดีกว่าที่จะเตรียมพร้อมสำหรับพวกมัน มากกว่าจะสมมติว่าพวกมันจะไม่เกิดขึ้น
11.11 เทคนิคในการวางแผนผลิตภัณฑ์ซอฟต์แวร์เพื่อรองรับการเปลี่ยนแปลง โดยเฉพาะการเขียนโปรแกรมแบบโครงสร้างพร้อมการทำเอกสารอินเทอร์เฟซโมดูลอย่างระมัดระวัง เป็นที่รู้จักกันดีแต่ยังไม่ถูกนำมาปฏิบัติอย่างสม่ำเสมอ นอกจากนี้ยังช่วย...
11.12 ใช้เทคนิคที่ขับเคลื่อนด้วยตาราง (table-driven techniques) ในทุกที่ที่เป็นไปได้ [ต้นทุนและขนาดของหน่วยความจำในปัจจุบันทำให้เทคนิคเหล่านี้ดียิ่งขึ้นไปอีก]
11.13 ใช้ภาษาระดับสูง, การทำงานในขณะคอมไพล์ (compile-time operations), การดึงการประกาศตัวแปรมาใช้โดยการอ้างอิง และเทคนิคการทำเอกสารในตัว เพื่อลดข้อผิดพลาดที่เกิดจากการเปลี่ยนแปลง
11.14 จัดการเปลี่ยนแปลงให้เป็นรอบๆ ในรูปแบบของเวอร์ชันที่ระบุหมายเลขไว้อย่างชัดเจน [ปัจจุบันกลายเป็นแนวปฏิบัติมาตรฐานแล้ว]
วางแผนองค์กรเพื่อรองรับการเปลี่ยนแปลง (Plan the Organization for Change)
11.15 ความไม่เต็มใจของนักเขียนโปรแกรมในการทำเอกสารประกอบงานออกแบบ ไม่ได้มาจากความขี้เกียจเท่ากับความลังเลที่จะต้องคอยปกป้องการตัดสินใจที่ผู้ออกแบบรู้อยู่แล้วว่าเป็นเพียงเรื่องชั่วคราว (Cosgrove)
11.16 การจัดโครงสร้างองค์กรเพื่อรองรับการเปลี่ยนแปลงนั้นยากกว่าการออกแบบระบบเพื่อรองรับการเปลี่ยนแปลงมาก
11.17 บอสของโครงการต้องพยายามทำให้ผู้จัดการและเจ้าหน้าที่ฝ่ายเทคนิคสามารถสับเปลี่ยนหน้าที่กันได้เท่าที่พรสวรรค์จะเอื้ออำนวย โดยเฉพาะอย่างยิ่ง ความต้องการที่จะย้ายผู้คนระหว่างบทบาททางเทคนิคและบทบาทการบริหารจัดการได้อย่างง่ายดาย
11.18 อุปสรรคต่อองค์กรแบบบันไดคู่ (dual-ladder organization) ที่มีประสิทธิภาพคือเรื่องทางสังคมวิทยา และต้องต่อสู้กับมันด้วยความระมัดระวังและพลังงานที่สม่ำเสมอ
11.19 มันเป็นเรื่องง่ายที่จะกำหนดอัตราเงินเดือนที่ตรงกันสำหรับขั้นบันไดที่สอดคล้องกัน แต่ต้องใช้มาตรการเชิงรุกที่รุนแรงเพื่อให้พวกเขามีเกียรติภูมิที่เท่าเทียมกัน: ได้แก่ ห้องทำงานที่เท่ากัน, บริการสนับสนุนที่เท่ากัน และการกระทำของฝ่ายบริหารที่ชดเชยให้มากกว่าปกติ
11.20 การจัดองค์กรแบบทีมผ่าตัดเป็นการจัดการกับทุกแง่มุมของปัญหานี้อย่างจริงจัง และมันคือคำตอบในระยะยาวสำหรับปัญหาเรื่ององค์กรที่ยืดหยุ่น
ก้าวไปข้างหน้าสองก้าวและถอยหลังหนึ่งก้าว—การบำรุงรักษาโปรแกรม (Two Steps Forward and One Step Back—Program Maintenance)
11.21 การบำรุงรักษาโปรแกรมแตกต่างจากการบำรุงรักษาฮาร์ดแวร์อย่างสิ้นเชิง โดยหลักแล้วประกอบด้วยการเปลี่ยนแปลงเพื่อซ่อมแซมข้อบกพร่องของงานออกแบบ, การเพิ่มฟังก์ชันใหม่ หรือการปรับให้เข้ากับการเปลี่ยนแปลงของสภาพแวดล้อมหรือการกำหนดค่าระบบ 11.22 ต้นทุนรวมตลอดอายุการใช้งานของการบำรุงรักษาโปรแกรมที่มีการใช้งานแพร่หลาย มักจะอยู่ที่ 40 เปอร์เซ็นต์หรือมากกว่าของต้นทุนการพัฒนา 11.23 ต้นทุนการบำรุงรักษาได้รับผลกระทบอย่างมากจากจำนวนผู้ใช้ ยิ่งผู้ใช้มากก็ยิ่งพบบั๊กมาก 11.24 Campbell ชี้ให้เห็นถึงกราฟรูปแบบ "ลดลงแล้วพุ่งสูงขึ้น" ที่น่าสนใจของจำนวนบั๊กต่อเดือนตลอดอายุขัยของผลิตภัณฑ์
11.25 การแก้ไขจุดบกพร่องหนึ่งจุด มีโอกาสสูง (20 ถึง 50 เปอร์เซ็นต์) ที่จะนำไปสู่การเกิดจุดบกพร่องใหม่อีกจุดหนึ่ง
11.26 หลังจากแก้ไขในแต่ละครั้ง เราต้องรันกรณีทดสอบทั้งหมดที่เคยรันกับระบบนั้น เพื่อรับประกันว่ามันจะไม่ได้รับความเสียหายในจุดที่มองไม่เห็น
11.27 วิธีการออกแบบโปรแกรมเพื่อกำจัดหรืออย่างน้อยก็ทำให้เห็นผลข้างเคียง (side effects) ได้ชัดเจน จะให้ผลตอบแทนมหาศาลในแง่ของต้นทุนการบำรุงรักษา
11.28 เช่นเดียวกับวิธีการนำงานออกแบบไปสร้างจริงโดยใช้คนน้อยลง มีอินเทอร์เฟซน้อยลง และส่งผลให้มีบั๊กน้อยลงตามไปด้วย
ก้าวไปข้างหน้าหนึ่งก้าวและถอยหลังหนึ่งก้าว—เอนโทรปีของระบบเพิ่มขึ้นตลอดอายุขัย (One Step Forward and One Step Back—System Entropy Rises over Lifetime)
11.29 Lehman และ Belady พบว่าจำนวนโมดูลทั้งหมดเพิ่มขึ้นเป็นเส้นตรงตามลำดับการออกเวอร์ชันของระบบปฏิบัติการขนาดใหญ่ (OS/360) แต่จำนวนโมดูลที่ได้รับผลกระทบกลับเพิ่มขึ้นเป็นเลขยกกำลังตามลำดับการออกเวอร์ชันนั้น
11.30 การซ่อมแซมทั้งหมดมีแนวโน้มที่จะทำลายโครงสร้าง และเพิ่มเอนโทรปี (entropy) และความไม่เป็นระเบียบของระบบ แม้แต่การบำรุงรักษาโปรแกรมที่ชำนาญที่สุดก็ทำได้เพียงประวิงเวลาการเสื่อมสลายของโปรแกรมไปสู่ความวุ่นวายที่ไม่อาจแก้ไขได้ จนต้องมีการออกแบบใหม่ทั้งหมดตั้งแต่ต้น [ความต้องการที่แท้จริงหลายอย่างในการอัปเกรดโปรแกรม เช่น เรื่องประสิทธิภาพ มักจะมุ่งโจมตีขอบเขตโครงสร้างภายในของมัน และบ่อยครั้งที่ขอบเขตดั้งเดิมเหล่านั้นเองที่เป็นต้นเหตุของข้อบกพร่องที่ปรากฏขึ้นในภายหลัง]
Chapter 12. Sharp Tools
12.1 ผู้จัดการโครงการจำเป็นต้องสร้างปรัชญาและจัดสรรทรัพยากรสำหรับการสร้างเครื่องมือส่วนกลาง และในขณะเดียวกันก็ต้องยอมรับความต้องการเครื่องมือส่วนบุคคลด้วย
12.2 ทีมที่สร้างระบบปฏิบัติการต้องการเครื่องเป้าหมาย (target machine) ของตนเองเพื่อใช้แก้ไขข้อผิดพลาด โดยต้องการหน่วยความจำสูงสุดมากกว่าความเร็วสูงสุด และต้องการนักเขียนโปรแกรมระบบเพื่อดูแลให้ซอฟต์แวร์มาตรฐานทันสมัยและพร้อมใช้งาน
12.3 เครื่องสำหรับแก้ไขข้อผิดพลาด หรือซอฟต์แวร์ของมัน จำเป็นต้องมีเครื่องมือวัดผล เพื่อให้สามารถนับและวัดพารามิเตอร์ของโปรแกรมทุกประเภทได้โดยอัตโนมัติ
12.4 ความต้องการใช้งานเครื่องเป้าหมายมีกราฟการเติบโตที่แปลกประหลาด: คือมีการใช้งานน้อยในช่วงแรกตามด้วยการเติบโตอย่างรวดเร็ว แล้วจึงคงที่
12.5 การแก้ไขข้อผิดพลาดในระบบ ก็เหมือนกับดาราศาสตร์ ที่มักจะทำในช่วงกลางคืนเป็นหลัก
12.6 การจัดสรรเวลาเครื่องเป้าหมายเป็นช่วงเวลาใหญ่ๆ ให้กับทีมย่อยทีละทีม พิสูจน์แล้วว่าเป็นวิธีที่ดีที่สุดในการจัดตารางเวลา ดีกว่าการให้หลายทีมสลับกันใช้งาน แม้ว่าตามทฤษฎีจะบอกเป็นอย่างอื่นก็ตาม
12.7 วิธีการจัดสรรเวลาคอมพิวเตอร์ที่มีอยู่น้อยนิดเป็นช่วงเวลาใหญ่ๆ นี้ ยังคงอยู่รอดมาได้ตลอด 20 ปี [นับถึงปี 1975] ของการเปลี่ยนแปลงทางเทคโนโลยี เพราะมันให้ผลิตภาพสูงสุด [และมันก็ยังคงเป็นเช่นนั้นในปี 1995]
12.8 หากคอมพิวเตอร์เป้าหมายเป็นเครื่องรุ่นใหม่ เราจำเป็นต้องมีโปรแกรมจำลองเชิงตรรกะสำหรับมัน เราจะได้รับมันมาเร็วกว่าเครื่องจริง และมันจะเป็นพาหนะแก้ไขข้อผิดพลาดที่วางใจได้แม้เราจะมีเครื่องจริงแล้วก็ตาม
12.9 คลังโปรแกรมหลักควรถูกแบ่งออกเป็น (1) ชุดของ "สนามเด็กเล่น" (playpens) ส่วนตัว (2) คลังย่อยสำหรับการรวมระบบ ซึ่งอยู่ระหว่างการทดสอบระบบในปัจจุบัน และ (3) เวอร์ชันที่ออกใช้งานจริง การแยกส่วนและขั้นตอนที่ชัดเจนจะช่วยให้เกิดการควบคุม
12.10 เครื่องมือที่ช่วยประหยัดแรงงานได้มากที่สุดในโครงการเขียนโปรแกรม น่าจะเป็นระบบแก้ไขข้อความ (text-editing system)
12.11 ความหนาของเอกสารระบบทำให้เกิดความไม่เข้าใจในรูปแบบใหม่ก็จริง [เช่นใน Unix เป็นต้น] แต่มันก็ยังดีกว่าการขาดแคลนเอกสารประกอบอย่างรุนแรงซึ่งมักพบบ่อยมาก 12.12 จงสร้างโปรแกรมจำลองประสิทธิภาพ จากภายนอกสู่ภายใน และจากบนลงล่าง เริ่มสร้างมันให้เร็วที่สุด และจงฟังเมื่อมันส่งเสียงเตือน
ภาษาระดับสูง (High-Level Language)
12.13 มีเพียงความขี้เกียจและความเฉื่อยชาเท่านั้นที่ขัดขวางการนำภาษาระดับสูงและการเขียนโปรแกรมแบบโต้ตอบมาใช้อย่างเป็นสากล [และในปัจจุบันพวกมันได้รับการยอมรับอย่างเป็นสากลแล้ว] 12.14 ภาษาระดับสูงไม่เพียงเพิ่มผลิตภาพเท่านั้น แต่ยังช่วยในการแก้ไขข้อผิดพลาดด้วย: คือมีบั๊กน้อยลงและหาได้ง่ายขึ้น 12.15 ข้อโต้แย้งแบบเดิมๆ เรื่องฟังก์ชัน, พื้นที่ของโค้ด และความเร็วของโค้ด ได้กลายเป็นเรื่องล้าสมัยไปแล้วด้วยความก้าวหน้าของภาษาและเทคโนโลยีคอมไพเลอร์ 12.16 ตัวเลือกเดียวที่สมเหตุสมผลสำหรับการเขียนโปรแกรมระบบในปัจจุบันคือ PL/I [ไม่เป็นความจริงอีกต่อไปแล้ว]
การเขียนโปรแกรมแบบโต้ตอบ (Interactive Programming)
12.17 ระบบแบบโต้ตอบจะไม่มีวันเข้ามาแทนที่ระบบแบบแบตช์ได้ในบางแอปพลิเคชัน [ยังคงเป็นความจริง] 12.18 การแก้ไขข้อผิดพลาดคือส่วนที่ยากและช้าที่สุดของการเขียนโปรแกรมระบบ และเวลาดำเนินการที่ช้าคือศัตรูตัวฉกาจของการแก้ไขข้อผิดพลาด 12.19 หลักฐานที่มีจำกัดแสดงให้เห็นว่า การเขียนโปรแกรมแบบโต้ตอบช่วยเพิ่มผลิตภาพในการเขียนโปรแกรมระบบได้อย่างน้อยสองเท่า
Chapter 13. The Whole and the Parts
13.1 ความพยายามทางสถาปัตยกรรมที่ละเอียดและถี่ถ้วนตามที่กล่าวในบทที่ 4, 5 และ 6 ไม่เพียงทำให้ผลิตภัณฑ์ใช้งานง่ายขึ้น แต่ยังทำให้สร้างง่ายขึ้นและลดจำนวนบั๊กของระบบที่ต้องตามหาลงด้วย
13.2 Vyssotsky กล่าวว่า "ความล้มเหลวจำนวนมหาศาลเกี่ยวข้องกับแง่มุมที่ไม่ได้มีการระบุไว้อย่างชัดเจน"
13.3 นานก่อนที่จะมีตัวโค้ด ข้อกำหนดจะต้องถูกส่งไปให้กลุ่มทดสอบภายนอกเพื่อตรวจสอบความครบถ้วนและความชัดเจน นักพัฒนาเองไม่สามารถทำสิ่งนี้ได้ (Vyssotsky)
13.4 "การออกแบบจากบนลงล่างของ Wirth [โดยการขัดเกลาทีละขั้นตอน] คือรูปแบบการเขียนโปรแกรมใหม่ที่สำคัญที่สุดในทศวรรษ [1965-1975]"
13.5 Wirth สนับสนุนให้ใช้สัญลักษณ์ในระดับที่สูงที่สุดเท่าที่จะเป็นไปได้ในแต่ละขั้นตอน
13.6 การออกแบบจากบนลงล่างที่ดีช่วยหลีกเลี่ยงบั๊กได้ในสี่ทาง
13.7 บางครั้งเราอาจต้องย้อนกลับไป ยกเลิกระดับบนสุด และเริ่มใหม่ทั้งหมด
13.8 การเขียนโปรแกรมแบบโครงสร้าง (Structured programming) ซึ่งคือการออกแบบโปรแกรมที่โครงสร้างการควบคุมประกอบด้วยชุดคำสั่งที่กำหนดไว้ซึ่งควบคุมบล็อกของโค้ด (แทนที่จะเป็นการแตกแขนงแบบสเปะสปะ) เป็นวิธีที่ถูกต้องในการหลีกเลี่ยงบั๊กและเป็นวิธีคิดที่ถูกต้อง
13.9 ผลการทดลองของ Gold แสดงให้เห็นว่า ความก้าวหน้าในการปฏิสัมพันธ์ครั้งแรกของรอบการแก้ไขข้อผิดพลาดแบบโต้ตอบนั้นมีมากกว่าการปฏิสัมพันธ์ครั้งต่อๆ ไปถึงสามเท่า ดังนั้นการวางแผนการแก้ไขข้อผิดพลาดอย่างรอบคอบก่อนจะเริ่มรันเครื่องจึงยังคงคุ้มค่า [ผมคิดว่าในปี 1995 ก็ยังคงเป็นเช่นนั้น]
13.10 ผมพบว่าการใช้งานระบบ [แก้ไขข้อผิดพลาดแบบโต้ตอบที่ตอบสนองเร็ว] ที่ดีอย่างเหมาะสม ต้องการเวลาที่โต๊ะทำงานสองชั่วโมงสำหรับทุกๆ สองชั่วโมงที่ใช้บนเครื่อง: หนึ่งชั่วโมงในการเก็บกวาดและทำเอกสารประกอบหลังจบจบรอบ และอีกหนึ่งชั่วโมงในการวางแผนการเปลี่ยนแปลงและการทดสอบสำหรับครั้งต่อไป
13.11 การแก้ไขข้อผิดพลาดในระบบ (ซึ่งตรงข้ามกับการแก้ไขข้อผิดพลาดในส่วนประกอบ) จะใช้เวลานานกว่าที่เราคาดไว้
13.12 ความยากของการแก้ไขข้อผิดพลาดในระบบทำให้ต้องใช้แนวทางที่เป็นระบบและมีการวางแผนอย่างถี่ถ้วน
13.13 เราควรเริ่มการแก้ไขข้อผิดพลาดในระบบหลังจากที่แต่ละชิ้นส่วนดูเหมือนจะทำงานได้แล้วเท่านั้น (ตรงข้ามกับแนวทาง "ประกอบเข้าด้วยกันแล้วลองดู" เพื่อไล่จับบั๊กอินเทอร์เฟซ และตรงข้ามกับการเริ่มทดสอบระบบเมื่อพบบั๊กในส่วนประกอบแล้วแต่ยังไม่ได้แก้ไข) [เรื่องนี้เป็นจริงอย่างยิ่งสำหรับงานในรูปแบบทีม]
13.14 การสร้างนั่งร้านสำหรับการแก้ไขข้อผิดพลาดและโค้ดทดสอบจำนวนมากเป็นเรื่องที่คุ้มค่า ซึ่งอาจจะมีปริมาณมากถึง 50 เปอร์เซ็นต์ของผลิตภัณฑ์ที่กำลังถูกทดสอบเลยก็ได้
13.15 เราต้องควบคุมและทำเอกสารประกอบการเปลี่ยนแปลงและเวอร์ชันต่างๆ โดยให้สมาชิกในทีมทำงานในสำเนาที่เป็น "สนามเด็กเล่น" (playpen) ของตนเอง
13.16 เพิ่มส่วนประกอบทีละหนึ่งชิ้นในระหว่างการแก้ไขข้อผิดพลาดในระบบ
13.17 Lehman และ Belady ให้หลักฐานว่ารอบการเปลี่ยนแปลงควรจะใหญ่และไม่บ่อย หรือไม่ก็เล็กมากและถี่มาก โดยแบบหลังจะมีความเสี่ยงต่อความไม่เสถียรมากกว่า [ทีมของ Microsoft ทำให้การเปลี่ยนแปลงที่เล็กและถี่นั้นได้ผล โดยการสร้างระบบใหม่ (rebuild) ในทุกๆ คืน]
Chapter 14. Hatching a Catastrophe
14.1 "โครงการล่าช้าไปหนึ่งปีได้อย่างไร? ... ทีละวันนั่นเอง"
14.2 ความล่าช้าของกำหนดการแบบวันต่อวันนั้นยากที่จะสังเกตเห็น ยากที่จะป้องกัน และยากที่จะชดเชยเวลาที่เสียไป ยิ่งกว่าเหตุร้ายครั้งใหญ่เสียอีก
14.3 ขั้นตอนแรกในการควบคุมโครงการขนาดใหญ่ที่มีกำหนดการรัดกุม คือการมีกำหนดการ ซึ่งประกอบด้วยหมุดหมายและวันที่ที่กำหนดไว้
14.4 หมุดหมายต้องเป็นเหตุการณ์ที่จับต้องได้ เฉพาะเจาะจง และวัดผลได้ โดยต้องถูกนิยามให้ชัดเจนและเฉียบคมเหมือนคมมีด
14.5 นักเขียนโปรแกรมมักจะไม่โกหกเรื่องความคืบหน้าของหมุดหมาย หากหมุดหมายนั้นชัดเจนมากจนเขาไม่สามารถหลอกตัวเองได้
14.6 การศึกษาพฤติกรรมการประมานการของผู้รับเหมาของรัฐบาลในโครงการขนาดใหญ่แสดงให้เห็นว่า การแก้ไขประมานการเวลาอย่างรอบคอบทุกสองสัปดาห์ไม่มีการเปลี่ยนแปลงอย่างมีนัยสำคัญเมื่อเวลาเริ่มต้นใกล้เข้ามา และในระหว่างทำกิจกรรม การประมานการที่สูงเกินไปจะค่อยๆ ลดลงอย่างสม่ำเสมอ ในขณะที่การประมานการที่ต่ำเกินไปจะไม่เปลี่ยนแปลงเลยจนกระทั่งเหลืออีกสามสัปดาห์จะถึงกำหนดการเสร็จสมบูรณ์
14.7 ความล่าช้าของกำหนดการที่เรื้อรังคือตัวฆ่าขวัญและกำลังใจ [Jim McCarthy จาก Microsoft กล่าวว่า "หากคุณพลาดเดดไลน์ครั้งหนึ่ง จงทำให้มั่นใจว่าคุณจะทำตามเดดไลน์ครั้งถัดไปให้ได้"]
14.8 ความกระตือรือร้น (hustle) เป็นสิ่งจำเป็นสำหรับทีมเขียนโปรแกรมที่ยอดเยี่ยม เช่นเดียวกับทีมเบสบอลที่ยอดเยี่ยม
14.9 ไม่มีอะไรจะแทนที่กำหนดการแบบเส้นทางวิกฤต (critical-path schedule) เพื่อที่จะบอกได้ว่าความล่าช้าแต่ละจุดส่งผลกระทบมากน้อยเพียงใด
14.10 การเตรียมแผนภูมิเส้นทางวิกฤตคือส่วนที่มีค่าที่สุดของการใช้งาน เพราะการวางโครงข่าย ระบุความสัมพันธ์ และประมานการส่วนงานต่างๆ บังคับให้ต้องมีการวางแผนที่เฉพาะเจาะจงอย่างมากตั้งแต่เนิ่นๆ
14.11 แผนภูมิแรกมักจะแย่เสมอ และเราต้องคิดแล้วคิดอีกในการทำแผนภูมิถัดไป
14.12 แผนภูมิเส้นทางวิกฤตคือคำตอบสำหรับข้อแก้ตัวที่บั่นทอนกำลังใจที่ว่า "อย่างไรเสีย ชิ้นส่วนอื่นก็ล่าช้าเหมือนกัน"
14.13 บอสทุกคนต้องการทั้งข้อมูลข้อยกเว้นที่ต้องการการตัดสินใจสั่งการ และภาพรวมสถานะสำหรับการเรียนรู้และการเตือนภัยล่วงหน้าในระยะไกล
14.14 การได้มาซึ่งสถานะที่แท้จริงนั้นเป็นเรื่องยาก เพราะผู้จัดการที่เป็นผู้น้อยมีสารพัดเหตุผลที่จะไม่เปิดเผยมัน
14.15 ด้วยการกระทำที่ผิดพลาด บอสสามารถรับประกันได้เลยว่าการเปิดเผยสถานะอย่างเต็มที่นั้นจะถูกระงับ ในทางกลับกัน การแยกแยะรายงานสถานะอย่างระมัดระวังและยอมรับพวกมันโดยไม่ตื่นตระหนกหรือเข้าแทรกแซง จะช่วยส่งเสริมการรายงานที่ตรงไปตรงมา
14.16 เราต้องมีเทคนิคการทบทวนเพื่อให้ผู้เล่นทุกคนทราบสถานะที่แท้จริง เพื่อจุดประสงค์นี้ กำหนดการหมุดหมายและเอกสารสรุปผลการเสร็จสิ้นจึงเป็นกุญแจสำคัญ
14.17 Vyssotsky: "ผมพบว่ามันสะดวกมากที่จะใส่ทั้งวันที่ 'ตามกำหนดการ' (scheduled) (วันที่ของบอส) และวันที่ 'ตามการประมานการ' (estimated) (วันที่ของผู้จัดการระดับล่างสุด) ไว้ในรายงานหมุดหมาย ผู้จัดการโครงการต้องไม่เข้าไปแตะต้องวันที่ตามการประมานการเหล่านั้น"
14.18 ทีมวางแผนและควบคุมขนาดเล็กที่ทำหน้าที่ดูแลรักษาบทสรุปหมุดหมาย มีค่าอย่างยิ่งสำหรับโครงการขนาดใหญ่
Chapter 15. The Other Face
15.1 สำหรับผลิตภัณฑ์โปรแกรม "อีกด้านหนึ่ง" ที่หันหาผู้ใช้ ซึ่งก็คือเอกสารประกอบ มีความสำคัญพอๆ กับด้านที่หันหาเครื่องจักร
15.2 แม้แต่โปรแกรมที่ใช้งานเป็นการส่วนตัวที่สุด เอกสารร้อยแก้วก็ยังจำเป็น เพราะความทรงจำของผู้เขียนจะเลือนลางไปตามกาลเวลา
15.3 ครูและผู้จัดการส่วนใหญ่ล้มเหลวในการปลูกฝังทัศนคติเรื่องการทำเอกสารประกอบที่จะสร้างแรงบันดาลใจไปตลอดชีวิต และเอาชนะความขี้เกียจหรือแรงกดดันจากกำหนดการได้
15.4 ความล้มเหลวนี้ไม่ได้เกิดจากการขาดความกระตือรือร้นหรือการพูดไม่เก่ง แต่เกิดจากการล้มเหลวในการ "แสดงให้เห็น" ว่าจะทำเอกสารประกอบอย่างมีประสิทธิภาพและประหยัดได้อย่างไร
15.5 เอกสารส่วนใหญ่มักล้มเหลวเพราะให้ภาพรวมน้อยเกินไป จงถอยออกมามองภาพกว้างแล้วค่อยๆ ซูมเข้าไปช้าๆ
15.6 เอกสารสำคัญสำหรับผู้ใช้ควรถูกร่างขึ้นก่อนที่โปรแกรมจะถูกสร้าง เพราะมันได้รวมการตัดสินใจในการวางแผนเบื้องต้นเอาไว้ โดยควรจะอธิบายสิ่งต่างๆ เก้าประการ (ดูรายละเอียดในบท)
15.7 โปรแกรมควรจะถูกส่งมอบพร้อมกับกรณีทดสอบสองสามกรณี ทั้งสำหรับข้อมูลที่ถูกต้อง ข้อมูลที่อยู่ขอบเขต และข้อมูลที่ไม่ถูกต้องอย่างชัดเจน
15.8 เอกสารประกอบโครงสร้างภายในของโปรแกรม สำหรับผู้ที่ต้องแก้ไขมัน ก็ต้องการภาพรวมแบบร้อยแก้วเช่นกัน ซึ่งควรประกอบด้วยห้าสิ่ง (ดูรายละเอียดในบท)
15.9 ผังงาน (flow chart) เป็นเอกสารประกอบโปรแกรมที่ถูกยกยอเกินจริงที่สุด ผังงานที่ละเอียดในทุกจุดคือสิ่งที่น่ารำคาญและล้าสมัยไปแล้วด้วยการมาของภาษาระดับสูง (ผังงานก็คือภาษาระดับสูงในรูปแบบแผนภาพนั่นเอง)
15.10 มีโปรแกรมเพียงไม่กี่โปรแกรมที่ต้องการผังงานที่ยาวเกินหนึ่งหน้า หากจำเป็นจริงๆ [ข้อกำหนดเอกสารตาม MILSPEC นั้นผิดพลาดอย่างยิ่งในจุดนี้]
15.11 เราต้องการกราฟโครงสร้างโปรแกรมจริงๆ ซึ่งไม่จำเป็นต้องทำตามมาตรฐานผังงานของ ANSI เลย
15.12 เพื่อให้เอกสารประกอบได้รับการบำรุงรักษาอยู่เสมอ สิ่งสำคัญยิ่งคือต้องรวมมันไว้ในซอร์สโปรแกรม มากกว่าจะเก็บแยกไว้เป็นเอกสารต่างหาก
15.13 แนวคิดสามประการที่เป็นกุญแจสำคัญในการลดภาระการทำเอกสารประกอบ:
- ใช้ส่วนของโปรแกรมที่ต้องมีอยู่แล้ว เช่น ชื่อและการประกาศตัวแปร เพื่อบรรจุเนื้อหาเอกสารประกอบให้มากที่สุดเท่าที่จะเป็นไปได้
- ใช้พื้นที่ว่างและรูปแบบเพื่อแสดงความสัมพันธ์ของการเป็นส่วนย่อยหรือการซ้อนกัน และเพื่อเพิ่มความสามารถในการอ่าน
-
แทรกเอกสารร้อยแก้วที่จำเป็นลงในโปรแกรมในรูปแบบของย่อหน้าความเห็น โดยเฉพาะในส่วนหัวของโมดูล (
module headers) 15.14 ในเอกสารประกอบสำหรับผู้ที่จะแก้ไขโปรแกรม ให้บอกว่า "ทำไม" สิ่งต่างๆ ถึงเป็นอย่างที่เป็นอยู่ มากกว่าบอกแค่ว่าพวกมันเป็นอย่างไร จุดประสงค์คือกุญแจสำคัญในการทำความเข้าใจ แม้แต่ไวยากรณ์ของภาษาระดับสูงก็ไม่สามารถสื่อสารจุดประสงค์ออกมาได้เลย 15.15 เทคนิคการเขียนโปรแกรมแบบทำเอกสารในตัว มีประโยชน์และทรงพลังที่สุดในภาษาระดับสูงที่ใช้กับระบบออนไลน์ ซึ่งเป็นเครื่องมือที่ทุกคนควรใช้อยู่แล้ว
Original Epilogue
E.1 ระบบซอฟต์แวร์อาจเป็นสิ่งที่สลับซับซ้อนและละเอียดอ่อนที่สุด (ในแง่ของจำนวนประเภทของชิ้นส่วนที่แตกต่างกัน) ในบรรดาสิ่งที่มนุษยชาติสร้างขึ้น E.2 หลุมน้ำมันดินของวิศวกรรมซอฟต์แวร์จะยังคงเหนียวหนืดเช่นนี้ต่อไปอีกนานแสนนาน