Image

สิ่งที่เราไม่เข้าใจ เราก็ไม่มีวันครอบครอง
GOETHE

โอ้ ขอให้มีผู้วิจารณ์ที่เรียบง่าย
ที่ไม่ต้องค้นคว้าลึกซึ้งจนปวดหัว
CRABBE

โปรแกรมคอมพิวเตอร์คือข้อความจากมนุษย์สู่เครื่องจักร ไวยากรณ์ที่ถูกจัดวางอย่างเคร่งครัดและนิยามที่พิถีพิถันล้วนมีไว้เพื่อทำให้เจตนาชัดเจนต่อเครื่องจักรที่ไร้ความเข้าใจ

แต่โปรแกรมที่ถูกเขียนขึ้นมีอีกหนึ่งใบหน้า นั่นคือด้านที่เล่าเรื่องราวของมันให้ผู้ใช้ที่เป็นมนุษย์ฟัง แม้กระทั่งโปรแกรมส่วนตัวที่สุด ก็ยังต้องการการสื่อสารแบบนี้อยู่ดี เพราะความจำของผู้เขียนที่ใช้งานโปรแกรมเองก็อาจเลือนลาง และเขาจำเป็นต้องได้รับการเตือนความจำเกี่ยวกับรายละเอียดของผลงานที่เขาสร้างขึ้น

ยิ่งสำหรับโปรแกรมที่เผยแพร่ให้ผู้อื่นใช้ ซึ่งผู้ใช้อยู่ห่างไกลจากผู้เขียนทั้งในด้านเวลาและสถานที่แล้ว เอกสารประกอบยิ่งมีความสำคัญมากขนาดไหน! สำหรับโปรแกรมที่เป็นผลิตภัณฑ์ ใบหน้าที่มีต่อผู้ใช้นั้นสำคัญพอๆ กับใบหน้าที่มีต่อเครื่องจักร

พวกเราส่วนใหญ่คงเคยสาปแช่งผู้เขียนนิรนามที่อยู่ห่างไกลของโปรแกรมที่แทบไม่มีเอกสารประกอบกันมาบ้าง และหลายคนจึงพยายามปลูกฝังทัศนคติเกี่ยวกับการทำเอกสารให้กับโปรแกรมเมอร์หน้าใหม่ ให้ติดตัวพวกเขาไปตลอดชีวิต เพื่อเอาชนะความขี้เกียจและแรงกดดันด้านกำหนดการส่งงาน แต่โดยรวมแล้วเราล้มเหลว ผมคิดว่าเราใช้วิธีที่ผิด

โธมัส เจ. วัตสัน ซีเนียร์ เคยเล่าเรื่องประสบการณ์แรกของเขาในฐานะพนักงานขายเครื่องบันทึกเงินสดในแถบตอนเหนือของรัฐนิวยอร์ก เขาเต็มไปด้วยความกระตือรือร้น ออกเดินทางพร้อมเกวียนที่บรรทุกเครื่องบันทึกเงินสด เขาทำงานในพื้นที่ของเขาอย่างขยันขันแข็ง แต่ไม่สามารถขายได้สักเครื่องเดียว เขารายงานเจ้านายด้วยความหดหู่ใจ ผู้จัดการฝ่ายขายฟังอยู่ครู่หนึ่งแล้วพูดว่า "ช่วยฉันยกเครื่องบันทึกเงินสดขึ้นเกวียน เทียมม้า แล้วออกไปกันใหม่" พวกเขาทำตามนั้น และทั้งสองก็ออกไปหาลูกค้าทีละราย โดยที่ผู้มีประสบการณ์มากกว่า สาธิตให้ดู ว่าขายเครื่องบันทึกเงินสดอย่างไร หลักฐานทั้งหมดบ่งชี้ว่าบทเรียนนั้นได้ผล

เป็นเวลาหลายปีที่ผมพยายามบรรยายให้กับชั้นเรียนวิศวกรรมซอฟต์แวร์อย่างขยันขันแข็งเกี่ยวกับความจำเป็นและความเหมาะสมของการทำเอกสารที่ดี ปลุกเร้าพวกเขาอย่างเอาจริงเอาจังและมีวาทศิลป์มากขึ้นเรื่อยๆ แต่มันก็ไม่เวิร์ก ผมคิดว่าพวกเขาเรียนรู้วิธีทำเอกสารที่ถูกต้องแล้ว แต่ล้มเหลวเพราะขาดความกระตือรือร้น จากนั้นผมก็ลองยกเครื่องบันทึกเงินสดขึ้นเกวียนบ้าง นั่นก็คือ สาธิตให้ดู ว่าต้องทำงานอย่างไร วิธีนี้ได้ผลดีกว่ามาก ดังนั้นส่วนที่เหลือของบทความนี้จะลดการปลุกระดมลงและเน้นที่ "วิธีการ" ของการทำเอกสารที่ดี

What Documentation Is Required? (ต้องใช้เอกสารอะไรบ้าง)

ผู้ใช้โปรแกรมแต่ละประเภทต้องการเอกสารในระดับที่แตกต่างกัน ไม่ว่าจะเป็นผู้ใช้ทั่วไป ผู้ใช้ที่ต้องพึ่งพาโปรแกรม หรือผู้ใช้ที่ต้องปรับเปลี่ยนโปรแกรมให้เข้ากับสถานการณ์หรือวัตถุประสงค์ที่เปลี่ยนไป

การใช้งานโปรแกรม ผู้ใช้ทุกคนต้องการคำอธิบายโปรแกรมในรูปแบบร้อยแก้ว เอกสารส่วนใหญ่มักล้มเหลวเพราะให้ภาพรวมน้อยเกินไป มีการอธิบายต้นไม้แต่ละต้น มีการคอมเมนต์เปลือกไม้และใบไม้ แต่ไม่มีแผนที่ของป่า ในการเขียนคำอธิบายรูปแบบร้อยแก้วที่มีประโยชน์ ให้ถอยออกมามองภาพใหญ่ แล้วค่อยๆ ขยับเข้ามา:

1 . วัตถุประสงค์. ฟังก์ชันหลักหรือเหตุผลที่ต้องมีโปรแกรมนี้คืออะไร?

2 . สภาพแวดล้อม. บนเครื่องจักร คอนฟิกฮาร์ดแวร์ และคอนฟิกระบบปฏิบัติการใดบ้างที่จะรันโปรแกรมนี้ได้?

3 . โดเมนและเรนจ์. โดเมนของอินพุตใดที่ถูกต้อง? เรนจ์ของเอาต์พุตใดที่สามารถปรากฏได้อย่างถูกต้อง?

4 . ฟังก์ชันที่ทำงานและอัลกอริทึมที่ใช้. โปรแกรมนี้ทำอะไรได้บ้างอย่างแม่นยำ?

5 . รูปแบบอินพุต-เอาต์พุต, ระบุอย่างแม่นยำและสมบูรณ์

6 . คำแนะนำการทำงาน, รวมถึงพฤติกรรมการสิ้นสุดการทำงานทั้งแบบปกติและผิดปกติ ตามที่เห็นบน Console และบนเอาต์พุต

7 . ตัวเลือก. ผู้ใช้มีตัวเลือกอะไรเกี่ยวกับฟังก์ชันบ้าง? และตัวเลือกเหล่านั้นระบุได้อย่างไร?

8 . เวลาทำงาน. ใช้เวลานานเท่าใดในการแก้ปัญหาขนาดที่กำหนดบนคอนฟิกที่กำหนด?

9 . ความแม่นยำและการตรวจสอบ. คำตอบควรมีความแม่นยำระดับไหน? มีวิธีการตรวจสอบความแม่นยำอะไรบ้างที่รวมอยู่ในโปรแกรม?

บ่อยครั้งที่ข้อมูลทั้งหมดนี้สามารถนำเสนอได้ในสามหรือสี่หน้า ซึ่งต้องให้ความสำคัญกับความกระชับและแม่นยำอย่างมาก เอกสารส่วนใหญ่ต้องถูกร่างขึ้นก่อนที่จะเขียนโปรแกรม เพราะมันบรรจุการตัดสินใจในการวางแผนขั้นพื้นฐานไว้

การเชื่อถือโปรแกรม คำอธิบายวิธีการใช้งานต้องเสริมด้วยคำอธิบายว่าเราจะรู้ได้อย่างไรว่าโปรแกรมทำงานได้ถูกต้อง ซึ่งก็คือการมีเทสเคส (Test cases) นั่นเอง

โปรแกรมทุกชุดที่ถูกส่งออกไปควรมีเทสเคสเล็กๆ ที่สามารถใช้เป็นประจำเพื่อสร้างความมั่นใจให้กับผู้ใช้ว่าเขาได้โปรแกรมที่ถูกต้องและโหลดเข้าเครื่องได้อย่างถูกต้อง

จากนั้นก็ต้องมีเทสเคสที่ละเอียดมากขึ้น ซึ่งโดยปกติจะรันหลังจากที่โปรแกรมถูกแก้ไขเท่านั้น เทสเคสเหล่านี้แบ่งออกเป็นสามส่วนของโดเมนข้อมูลอินพุต:

1 . Mainline cases (เคสหลัก) ที่ทดสอบฟังก์ชันหลักของโปรแกรมสำหรับข้อมูลที่พบได้ทั่วไป.

2 . เคสที่เกือบไม่ถูกต้องแต่ยังใช้ได้ (Barely legitimate cases) ที่สำรวจขอบของโดเมนข้อมูลอินพุต เพื่อให้แน่ใจว่าค่าที่มากที่สุด ค่าที่น้อยที่สุด และ exception ที่ถูกต้องทุกชนิดทำงานได้

3 . เคสที่เกือบจะถูกต้องแต่ผิด (Barely illegitimate cases) ที่สำรวจขอบเขตของโดเมนจากอีกด้านหนึ่ง เพื่อให้แน่ใจว่าอินพุตที่ไม่ถูกต้องสร้างข้อความ diagnostic ที่เหมาะสม

การแก้ไขโปรแกรม การปรับเปลี่ยนหรือแก้ไขโปรแกรมต้องการข้อมูลมากกว่ามาก แน่นอนว่ารายละเอียดทั้งหมดเป็นสิ่งจำเป็น และมันอยู่ใน source code ที่มีคอมเมนต์อย่างดี สำหรับผู้แก้ไข รวมถึงผู้ใช้ทั่วไป ความต้องการที่สำคัญที่สุดคือภาพรวมที่ชัดเจนและคมชัด คราวนี้เป็นภาพรวมของโครงสร้างภายใน องค์ประกอบของภาพรวมดังกล่าวมีอะไรบ้าง?

1 . ผังงาน (flow chart) หรือกราฟโครงสร้างโปรแกรมย่อย (subprogram structure graph) ซึ่งจะกล่าวถึงเพิ่มเติมในภายหลัง

2 . คำอธิบายที่สมบูรณ์ของอัลกอริทึมที่ใช้ หรือการอ้างอิงถึงคำอธิบายดังกล่าวในเอกสารอ้างอิง

3 . คำอธิบายโครงสร้างของไฟล์ทั้งหมดที่ใช้

4 . ภาพรวมของโครงสร้าง pass—ลำดับที่ข้อมูลหรือโปรแกรมถูกเรียกจากเทปหรือดิสก์—และสิ่งที่ทำสำเร็จในแต่ละ pass

5 . การอภิปรายเกี่ยวกับการปรับเปลี่ยนที่คาดการณ์ไว้ในการออกแบบดั้งเดิม ลักษณะและตำแหน่งของ hooks และ exits และการอภิปรายอย่างละเอียดเกี่ยวกับแนวคิดของผู้เขียนดั้งเดิมว่าการปรับเปลี่ยนใดที่น่าจะเป็นประโยชน์และจะดำเนินการอย่างไร ข้อสังเกตของเขาเกี่ยวกับกับดักที่ซ่อนอยู่ก็มีประโยชน์เช่นกัน

The Flow-Chart Curse (คำสาปของผังงาน)

ผังงาน (flow chart) เป็นรูปแบบเอกสารประกอบโปรแกรมที่ถูกกล่าวขยายเกินจริงมากที่สุด โปรแกรมจำนวนมากไม่จำเป็นต้องมีผังงานเลย มีโปรแกรมเพียงไม่กี่ตัวเท่านั้นที่ต้องการผังงานเกินกว่าหนึ่งหน้า

ผังงานแสดงโครงสร้างการตัดสินใจของโปรแกรม ซึ่งเป็นเพียงแง่มุมหนึ่งของโครงสร้างเท่านั้น ผังงานแสดงโครงสร้างการตัดสินใจได้อย่างสวยงามเมื่ออยู่ในหน้าเดียว แต่ภาพรวมจะพังทลายลงอย่างมากเมื่อมีหลายหน้าที่ถูกเชื่อมติดกันด้วยหมายเลข exit และ connector

ผังงานหน้าเดียวสำหรับโปรแกรมขนาดใหญ่จะกลายเป็นแผนภาพของโครงสร้างโปรแกรม และของเฟสหรือขั้นตอนต่างๆ ในแง่นี้มันมีประโยชน์มาก รูปที่ 15.1 แสดงกราฟโครงสร้างโปรแกรมย่อยดังกล่าว

รูปที่ 15.1. กราฟโครงสร้างโปรแกรม (โดยความอนุเคราะห์ของ W. V. Wright)

Image

แน่นอนว่ากราฟโครงสร้างแบบนี้ไม่จำเป็นต้องทำตามมาตรฐาน ANSI flow-charting ที่ถูกสร้างขึ้นมาอย่างยากลำบาก กฎทั้งหมดเกี่ยวกับรูปร่างกล่อง connector หมายเลข ฯลฯ ล้วนมีไว้เพื่อทำให้ผังงานที่มีรายละเอียดอ่านเข้าใจได้เท่านั้น

อย่างไรก็ตาม ผังงานแบบละเอียดทีละขั้นตอน (detailed blow-by-blow flow chart) เป็นสิ่งที่น่ารำคาญที่ล้าสมัย เหมาะสำหรับการสอนผู้เริ่มต้นให้เข้าใจการคิดเชิงอัลกอริทึมเท่านั้น เมื่อ Goldstine และ von Neumann นำเสนอมันครั้งแรก [1] กล่องเล็กๆ และเนื้อหาภายในทำหน้าที่เป็นภาษาระดับสูง จัดกลุ่มคำสั่งภาษาเครื่องที่เข้าใจยากให้เป็นกลุ่มที่มีความหมาย ตามที่ Iverson สังเกตเห็นตั้งแต่แรก [2] ในภาษาระดับสูงที่เป็นระบบ การจัดกลุ่มก็เกิดขึ้นแล้ว และแต่ละกล่องก็มีคำสั่งอยู่หนึ่งคำสั่ง ( รูปที่ 15.2 ) จากนั้นตัวกล่องเองก็กลายเป็นเพียงการฝึกหัดร่างที่แสนน่าเบื่อและเปลืองพื้นที่ ควรจะกำจัดมันทิ้งไป แล้วก็จะเหลือเพียงลูกศรเท่านั้น ลูกศรที่เชื่อมคำสั่งหนึ่งไปยังคำสั่งถัดไปนั้นซ้ำซ้อน ให้ลบมันทิ้งไป เหลือเพียง GO TO เท่านั้น และถ้าเราทำตามแนวปฏิบัติที่ดีและใช้ block structure เพื่อลดจำนวน GO TO ก็จะเหลือลูกศรไม่มาก แต่ลูกศรเหล่านี้ช่วยให้เข้าใจได้อย่างมหาศาล เราอาจวาดมันลงบน listing และกำจัดผังงานทิ้งไปเลยก็ได้

รูปที่ 15.2. การเปรียบเทียบระหว่างผังงานและโปรแกรม PL/I ที่สอดคล้องกัน [ตัดทอนและดัดแปลงจาก Figs. 15–41, 15–44 ใน Data Processing and Computer Programming: A Modular Approach โดย Thomas J. Cashman และ William J. Keys (Harper & Row, 1971).]

Image

Image

ในความเป็นจริง การทำผังงานถูกพร่ำสอนมากกว่าที่ปฏิบัติจริง ผมไม่เคยเห็นโปรแกรมเมอร์ที่มีประสบการณ์คนไหนที่ทำผังงานละเอียดเป็นประจำก่อนเริ่มเขียนโปรแกรมเลย ในที่ที่มาตรฐานขององค์กรกำหนดให้ต้องมีผังงาน มันมักจะถูกทำหลังจากเขียนโปรแกรมเสร็จเกือบทุกครั้ง หลายองค์กรภูมิใจที่ใช้โปรแกรมสร้าง "เครื่องมือออกแบบที่ขาดไม่ได้" นี้จากโค้ดที่เสร็จสมบูรณ์แล้ว ผมคิดว่าประสบการณ์สากลนี้ไม่ใช่การเบี่ยงเบนจากแนวปฏิบัติที่ดีที่น่าอับอายและน่าเสียใจ ที่ต้องยอมรับด้วยหัวเราะแห้งๆ เท่านั้น แต่มันคือการใช้วิจารณญาณที่ดี และมันสอนเราเกี่ยวกับประโยชน์ของผังงาน

อัครสาวกเปโตรพูดถึงผู้เปลี่ยนมานับถือใหม่ที่เป็นคนต่างชาติและกฎหมายของชาวยิวว่า "เหตุใดจึงต้องวางภาระหนักบนหลังของพวกเขา ที่ทั้งบรรพบุรุษของเราและตัวเราเองก็แบกไม่ไหว?" (กิจการ 15:10, TEV) ผมอยากพูดแบบเดียวกันเกี่ยวกับโปรแกรมเมอร์หน้าใหม่และแนวปฏิบัติที่ล้าสมัยอย่างการทำผังงาน

Self-Documenting Programs (โปรแกรมที่อธิบายตัวเองได้)

หลักการพื้นฐานของการประมวลผลข้อมูลสอนเราถึงความผิดพลาดของการพยายามรักษาไฟล์อิสระหลายไฟล์ให้สอดคล้องกัน มันดีกว่ามากที่จะรวมพวกมันเข้าเป็นไฟล์เดียว โดยแต่ละ record มีข้อมูลทั้งหมดที่ทั้งสองไฟล์เคยมีเกี่ยวกับ key ที่กำหนด

แต่การปฏิบัติของเราในการทำเอกสารประกอบโปรแกรมกลับขัดแย้งกับคำสอนของเราเอง เรามักจะพยายามรักษารูปแบบที่เครื่องอ่านได้ของโปรแกรม และชุดเอกสารที่มนุษย์อ่านได้แยกต่างหาก ซึ่งประกอบด้วยร้อยแก้วและผังงาน

ผลลัพธ์ที่ได้ก็ยืนยันคำสอนของเราเกี่ยวกับความผิดพลาดของไฟล์ที่แยกจากกันอีกครั้ง เอกสารประกอบโปรแกรมนั้นแย่เป็นที่เลื่องลือ และการบำรุงรักษาก็แย่ยิ่งกว่า การเปลี่ยนแปลงที่ทำในโปรแกรมไม่ปรากฏบนเอกสารอย่างทันท่วงที แม่นยำ และสม่ำเสมอ

วิธีแก้ปัญหานี้ ผมคิดว่า คือการรวมไฟล์เข้าด้วยกัน โดยผนวกเอกสารเข้าไปใน source program ซึ่งในขณะเดียวกันก็เป็นแรงจูงใจที่ทรงพลังต่อการบำรุงรักษาที่เหมาะสม และเป็นหลักประกันว่าเอกสารจะพร้อมใช้งานสำหรับผู้ใช้โปรแกรมเสมอ โปรแกรมแบบนี้เรียกว่า self-documenting (โปรแกรมที่อธิบายตัวเองได้) .

แน่นอนว่ามันจะยุ่งยาก (แต่ไม่ถึงกับเป็นไปไม่ได้) ถ้าต้องรวมผังงานเข้าไปด้วย แต่ถ้าเรายอมรับว่าผังงานล้าสมัยและการใช้ภาษาระดับสูงเป็นหลัก การรวมโปรแกรมและเอกสารเข้าด้วยกันก็จะกลายเป็นเรื่องที่สมเหตุสมผล

การใช้ source program เป็นสื่อสำหรับเอกสารทำให้เกิดข้อจำกัดบางอย่าง ในอีกด้านหนึ่ง การเข้าถึง source program อย่างใกล้ชิดทีละบรรทัดสำหรับผู้อ่านเอกสารทำให้เกิดเทคนิคใหม่ๆ ได้ ถึงเวลาแล้วที่จะคิดค้นแนวทางและวิธีการใหม่ๆ อย่างสิ้นเชิงสำหรับการทำเอกสารโปรแกรม

ในฐานะเป้าหมายหลัก เราต้องพยายามลดภาระของการทำเอกสาร ซึ่งเป็นภาระที่ทั้งเราและรุ่นก่อนของเราต่างก็ไม่สามารถแบกรับได้สำเร็จ

แนวทาง แนวคิดแรกคือการใช้ส่วนต่างๆ ของโปรแกรมที่ต้องมีอยู่แล้วตามหลักภาษาโปรแกรม เพื่อช่วยในการทำเอกสารให้มากที่สุด ดังนั้น labels, declaration statements และ symbolic names ล้วนถูกนำมาใช้เพื่อสื่อความหมายให้มากที่สุดแก่ผู้อ่าน

แนวคิดที่สองคือการใช้พื้นที่และรูปแบบให้มากที่สุดเพื่อปรับปรุงความสามารถในการอ่านและแสดงลำดับชั้นและการซ้อนกัน (nesting)

แนวคิดที่สามคือการแทรกเอกสารรูปแบบร้อยแก้วที่จำเป็นลงในโปรแกรมในรูปแบบย่อหน้าของคอมเมนต์ โปรแกรมส่วนใหญ่มักจะมีคอมเมนต์แบบทีละบรรทัดมากพอแล้ว โปรแกรมที่ถูกผลิตขึ้นเพื่อให้เป็นไปตามมาตรฐานองค์กรที่เข้มงวดสำหรับ "เอกสารที่ดี" มักจะมีมากเกินไปด้วยซ้ำ อย่างไรก็ตาม แม้แต่โปรแกรมเหล่านี้ก็มักจะขาดคอมเมนต์แบบย่อหน้าที่ให้ความเข้าใจและภาพรวมแก่ทั้งโปรแกรมอย่างแท้จริง

เนื่องจากเอกสารถูกสร้างไว้ในโครงสร้าง การตั้งชื่อ และรูปแบบของโปรแกรม เอกสารส่วนใหญ่ ต้อง ทำตั้งแต่ตอนที่เขียนโปรแกรมครั้งแรก แต่นั่นก็เป็นเวลาที่ ควร จะเขียนมันด้วยเช่นกัน เนื่องจากแนวทาง self-documentation ช่วยลดงานพิเศษลง จึงมีอุปสรรคน้อยกว่าในการทำมันตั้งแต่ตอนนั้น

เทคนิคบางประการ รูปที่ 15.3 แสดงโปรแกรม PL/I แบบ self-documenting [3] ตัวเลขในวงกลมไม่ใช่ส่วนหนึ่งของโปรแกรม แต่เป็น meta-documentation ที่เชื่อมโยงกับเนื้อหาที่กล่าวถึง

1 . ใช้ชื่อ job แยกต่างหากสำหรับแต่ละรัน และเก็บ run log ที่แสดงว่าทดลองอะไร เมื่อไหร่ และผลลัพธ์อะไร ถ้าชื่อประกอบด้วยส่วนที่จำได้ง่าย (mnemonic) (เช่น QLT ) และส่วนต่อท้ายที่เป็นตัวเลข (เช่น 4 ) ส่วนต่อท้ายสามารถใช้เป็นหมายเลขรัน เชื่อมโยง listing และ log เข้าด้วยกัน เทคนิคนี้ต้องใช้ job card ใหม่สำหรับแต่ละรัน แต่สามารถทำเป็นชุดๆ โดยทำซ้ำข้อมูลทั่วไป

2 . ใช้ชื่อโปรแกรมที่จำได้ง่าย แต่มีตัวระบุเวอร์ชันด้วย นั่นคือ สมมติว่าจะมีหลายเวอร์ชัน ในที่นี้ index คือเลขหลักสุดท้ายของปี 1967

3 . ผนวกคำอธิบายรูปแบบร้อยแก้วเป็นคอมเมนต์ใน PROCEDURE

4 . อ้างอิงถึงเอกสารมาตรฐานเพื่อจัดทำเอกสารอัลกอริทึมพื้นฐานทุกครั้งที่เป็นไปได้ ซึ่งช่วยประหยัดพื้นที่ มักจะชี้ไปยังคำอธิบายที่ละเอียดกว่าที่เราจะให้ได้ และช่วยให้ผู้อ่านที่มีความรู้ข้ามไปได้ด้วยความมั่นใจว่าเขาเข้าใจสิ่งที่เราหมายถึง

5 . แสดงความสัมพันธ์กับอัลกอริทึมในหนังสือ:

ก) การเปลี่ยนแปลง (changes)

ข) การทำให้เฉพาะเจาะจง (specialization)

ค) การแทนค่า (representation)

6 . ประกาศตัวแปรทั้งหมด ใช้ชื่อที่จำได้ง่าย (mnemonic names) ใช้คอมเมนต์เพื่อเปลี่ยน DECLARE ให้เป็นคำอธิบายที่สมบูรณ์ (complete legend) สังเกตว่ามันมีชื่อและคำอธิบายโครงสร้างอยู่แล้ว จึงต้องการเพียงคำอธิบาย วัตถุประสงค์ เพิ่มเติมเท่านั้น การทำเช่นนี้จะช่วยหลีกเลี่ยงการกล่าวชื่อและคำอธิบายโครงสร้างซ้ำอีกครั้งในส่วนที่แยกต่างหาก

7 . ทำเครื่องหมายการ initialization ด้วย label

8 . ติด label ให้กับ statements เป็นกลุ่มเพื่อแสดงความสอดคล้องกับ statements ในคำอธิบายอัลกอริทึมในเอกสารอ้างอิง

9 . ใช้การเยื้อง (indenting) เพื่อแสดงโครงสร้างและการจัดกลุ่ม

10 . เพิ่มลูกศรแสดงการไหลของลอจิก (logical flow arrows) ลงใน listing ด้วยมือ ซึ่งมีประโยชน์มากในการ debugging และการแก้ไข ลูกศรเหล่านี้อาจถูกแทรกในขอบด้านขวาของช่องว่างคอมเมนต์ และทำให้เป็นส่วนหนึ่งของข้อความที่เครื่องอ่านได้

11 . ใช้ line comments หรือ remark ในสิ่งที่ไม่ง่ายต่อการเข้าใจ ถ้าใช้เทคนิคข้างต้นแล้ว สิ่งเหล่านี้จะสั้นและมีจำนวนน้อยกว่าที่เคยเป็น

12 . ใส่หลาย statements ในบรรทัดเดียว หรือหนึ่ง statement ในหลายบรรทัดเพื่อให้สอดคล้องกับการจัดกลุ่มความคิดและแสดงความสอดคล้องกับคำอธิบายอัลกอริทึมอื่นๆ

รูปที่ 15.3. โปรแกรมแบบ self-documenting

Image

แล้วทำไมไม่ทำล่ะ? อะไรคือข้อเสียของแนวทางการทำเอกสารแบบนี้? มีอยู่หลายข้อ ซึ่งเคยเป็นปัญหาจริงๆ แต่กำลังกลายเป็นเรื่องไม่เป็นจริงตามยุคสมัยที่เปลี่ยนไป

ข้อโต้แย้งที่ร้ายแรงที่สุดคือการเพิ่มขนาดของ source code ที่ต้องจัดเก็บ ในขณะที่วงการซอฟต์แวร์เคลื่อนไปสู่การจัดเก็บ source code แบบออนไลน์มากขึ้นเรื่อยๆ เรื่องนี้กลายเป็นข้อพิจารณาที่เพิ่มมากขึ้น ผมพบว่าตัวเองเขียนคอมเมนต์สั้นลงในโปรแกรม APL ซึ่งจะอยู่บนดิสก์ เมื่อเทียบกับโปรแกรม PL/I ที่ผมจะจัดเก็บเป็นบัตรเจาะรู (cards)

แต่ในขณะเดียวกัน เราก็กำลังเคลื่อนไปสู่การจัดเก็บเอกสารรูปแบบร้อยแก้วแบบออนไลน์เพื่อการเข้าถึงและอัปเดตผ่านการแก้ไขข้อความด้วยคอมพิวเตอร์ ดังที่แสดงไว้ข้างต้น การรวมร้อยแก้วและโปรแกรมเข้าด้วยกัน ช่วยลด จำนวนตัวอักษรทั้งหมดที่ต้องจัดเก็บ

คำตอบเดียวกันนี้ใช้กับข้อโต้แย้งที่ว่าโปรแกรมแบบ self-documenting ต้องใช้การกดแป้นพิมพ์มากกว่า เอกสารที่พิมพ์ต้องใช้การกดแป้นพิมพ์อย่างน้อยหนึ่งครั้งต่อตัวอักษรต่อหนึ่งร่าง โปรแกรมแบบ self-documenting มีจำนวนตัวอักษรรวมน้อยกว่า และยังมีการกดแป้นพิมพ์ต่อตัวอักษรน้อยกว่า เพราะไม่ต้องพิมพ์ร่างใหม่ซ้ำ

แล้วผังงานและกราฟโครงสร้างล่ะ? ถ้าใช้เฉพาะกราฟโครงสร้างระดับสูงสุด ก็อาจเก็บไว้เป็นเอกสารแยกต่างหากได้อย่างปลอดภัย เพราะมันไม่ต้องถูกเปลี่ยนแปลงบ่อย แต่มันก็สามารถรวมเข้าไปใน source program เป็นคอมเมนต์ได้ ซึ่งดูเป็นสิ่งที่ชาญฉลาด

เทคนิคที่ใช้ข้างต้นสามารถนำไปใช้กับโปรแกรมภาษา assembly ได้มากน้อยแค่ไหน? ผมคิดว่าแนวทางพื้นฐานของ self-documentation สามารถนำไปใช้ได้อย่างสมบูรณ์ พื้นที่และรูปแบบมีอิสระน้อยกว่า และจึงไม่สามารถใช้ได้อย่างยืดหยุ่นนัก ชื่อและการประกาศโครงสร้างสามารถนำมาใช้ประโยชน์ได้อย่างแน่นอน Macros สามารถช่วยได้อย่างมาก การใช้คอมเมนต์แบบย่อหน้าอย่างกว้างขวางเป็นแนวปฏิบัติที่ดีในทุกภาษา

แต่แนวทาง self-documentation ถูกกระตุ้นโดยการใช้ภาษาระดับสูง และพบพลังและการให้เหตุผลที่ยิ่งใหญ่ที่สุดในภาษาระดับสูงที่ใช้กับระบบออนไลน์ ไม่ว่าจะเป็นแบบแบตช์หรืออินเทอร์แอคทีฟ อย่างที่ผมได้โต้แย้งมา ภาษาและระบบดังกล่าวช่วยโปรแกรมเมอร์ได้อย่างทรงพลัง เนื่องจากเครื่องจักรถูกสร้างขึ้นมาเพื่อมนุษย์ ไม่ใช่มนุษย์เพื่อเครื่องจักร การใช้ภาษาระดับสูงจึงสมเหตุสมผลในทุกๆ ด้าน ทั้งทางเศรษฐกิจและทางมนุษย์