- กำลังพยายามพัฒนาทักษะด้านการออกแบบซอฟต์แวร์ และมีคนแนะนำให้ลองศึกษาจากโค้ดเบสที่ออกแบบมาดีซึ่งมีอยู่แล้ว
- จึงสงสัยว่า ในบรรดาโค้ดเบสที่เข้าถึงได้สาธารณะ มีอะไรบ้างที่ถือเป็นมาตรฐานระดับทองของการออกแบบซอฟต์แวร์
1. โค้ดเบสที่แนะนำ
- โปรเจ็กต์ขนาดใหญ่/ตัวแทนสำคัญ
- Git, Postgres, CPython
- "lieutenants model" ของ Linux Kernel
- UNIX v6, BSDs
- เฟรมเวิร์ก/ไลบรารี
- ระบบ/เซิร์ฟเวอร์
- เกม/กรณีพิเศษ
- สื่อการสอน/แหล่งเรียนรู้
- อื่น ๆ
- Monocypher (ไลบรารีเข้ารหัสลับ)
- อิมพลีเมนเทชันของภาษา Tcl
2. การอ่านโค้ด vs การเรียนจากเอกสาร/การออกแบบ
- ข้อจำกัดของการดูแต่โค้ด
- โค้ดเบสแสดงให้เห็นการอิมพลีเมนต์ แต่ซ่อนเจตนาในการออกแบบและการแลกเปลี่ยนข้อดีข้อเสียไว้
- ความสำคัญของเอกสารการออกแบบ
- บันทึกการตัดสินใจอย่าง ADR (Architectural Decision Records), Rust RFCs, Python PEPs มีประโยชน์ต่อการเรียนรู้การออกแบบมากกว่า
- การเขียนเอกสารออกแบบด้วยตัวเองก็อาจเป็นการฝึกที่ดีได้
- หนังสือ·เอกสารแนะนำ
3. แนวคิดการเรียนรู้ที่เน้นการลงมือปฏิบัติ
- ประสบการณ์และการลองผิดลองถูก
- การออกแบบเป็นสิ่งที่เรียนรู้ได้จากการเจอปัญหาซ้ำ ๆ และเรียนรู้วิธีหลีกเลี่ยงมัน
- แค่อ่านโค้ดอย่างเดียวไม่ทำให้เกิดการเรียนรู้ ต้องลงมือเขียนเองและแก้ปัญหาจากความล้มเหลวจึงจะได้เรียนรู้
- การเรียนรู้ตามความสนใจ
- การสร้างโปรเจ็กต์ที่ตัวเองสนใจจะทำให้เรียนรู้ได้ลึกกว่า
- ต้นทุนของความล้มเหลวที่ต่ำ
- ซอฟต์แวร์มีต้นทุนของความล้มเหลวต่ำกว่าวิศวกรรมกายภาพ จึงเหมาะกับการเรียนรู้ผ่านการลองและการพลาด
4. ข้อถกเถียงเรื่องธรรมชาติของวิศวกรรมซอฟต์แวร์
- แนวคิดว่ายังเป็นวิศวกรรมที่ไม่สุกงอม
- ถ้ามีวิศวกรห้าคนแล้วได้คำตอบต่างกันห้าแบบ นั่นอาจเป็นหลักฐานว่ามันยังไม่สุกงอมในฐานะวิศวกรรม
- มุมมองว่าเอื้อต่อการทดลอง
- ซอฟต์แวร์มีข้อจำกัดน้อย จึงมีวิธีแก้ได้หลากหลาย และไม่ได้มีคำตอบตายตัวแบบวิศวกรรมกายภาพ
- เส้นแบ่งระหว่างศิลปะกับวิศวกรรม
- การออกแบบอาจเป็นกิจกรรมเชิงศิลปะที่มีองค์ประกอบด้านสุนทรียะ แต่ในแง่ของการตอบโจทย์การใช้งานก็เป็นวิศวกรรม
- ซอฟต์แวร์อยู่กึ่งกลางระหว่างความยืดหยุ่นแบบศิลปะและความเคร่งครัดแบบวิศวกรรม
5. วิธีเรียนรู้ทางเลือกอื่น
- วิเคราะห์โค้ดที่แย่
- ไม่ใช่แค่โค้ดที่ออกแบบดีเท่านั้น การ ลองแก้โค้ดเบสที่ย่ำแย่ ก็ให้ผลการเรียนรู้สูงมาก
- เรียนจากโค้ดเบสของตัวเอง
- หลายคนมองว่าโค้ดเบสภายในทีมเป็นแหล่งเรียนรู้ที่ได้ประโยชน์มากที่สุด
- แต่ถ้าโค้ดของทีมคุณแย่ ก็อาจต้องดูตัวอย่างภายนอกควบคู่กันไป
- การเรียนรู้ตามโดเมน
- การอ่านโค้ดเบสที่คล้ายกับปัญหาที่คุณอยากแก้ เป็นวิธีที่ได้ผลที่สุด
อินไซต์สำคัญ
- โค้ดเบสที่ออกแบบดีมีประโยชน์ แต่ การเรียนรู้ต้องควบคู่ไปกับการเข้าใจเจตนาการออกแบบและการลองผิดลองถูก
- มากกว่าการอ่านโค้ด สิ่งสำคัญคือ เอกสารการออกแบบและบันทึกการตัดสินใจ
- โปรเจ็กต์คุณภาพสูงที่เป็นตัวแทนสำคัญ (Git, Postgres, CPython, Rust std ฯลฯ) มีคุณค่าสูงในการเรียนรู้
- ไม่ใช่แค่โค้ดดีเท่านั้น การเรียนรู้จาก โค้ดที่แย่และโค้ดของตัวเอง ก็มีความเป็นรูปธรรมมากกว่าในระยะยาว
สรุปความคิดเห็นเด่น
คำแนะนำโค้ดเบสเด่น ๆ (CraigJPerry)
- Postfix mail server
- มีสถาปัตยกรรมที่เน้นความปลอดภัย และแสดงโครงสร้างคล้าย microservices ได้ตั้งแต่ก่อนแนวคิดนี้จะเป็นที่นิยม
- ถ้า microservices สมัยใหม่เน้นการกระจายงานในองค์กรขนาดใหญ่ Postfix ถูกออกแบบเพื่อ ความปลอดภัยและความเรียบง่าย
- Spring Framework
- สะท้อนวัฒนธรรมที่ใส่ใจความต้องการของนักพัฒนา Java ในองค์กรอย่างลึกซึ้ง
- เป็นตัวอย่างของการออกแบบที่ยึดผู้ใช้เป็นศูนย์กลาง
- Git
- ถ้าเข้าใจแนวคิด object database (blob, tree, commit) และ references แล้ว ส่วนที่เหลือคือการขยายต่อยอดอย่างค่อยเป็นค่อยไป
- ถูกยกเป็นตัวอย่างของการออกแบบที่ ขยายจากแนวคิดหลักอย่างสม่ำเสมอ
- Varnish
- เป็น reverse proxy ประสิทธิภาพสูง และยังเป็นโค้ดเบสที่จัดวางได้ดีจนใช้เป็นสื่อการเรียนรู้ได้
- Linux Kernel Lieutenants Model
- แม้จะไม่ใช่โค้ดเบส แต่ก็น่าศึกษาในฐานะ โมเดลการจัดการซอฟต์แวร์ขนาดใหญ่
- สิ่งเหล่านี้ไม่ใช่เพียง “โค้ดที่ออกแบบดี” แต่เป็น กรณีตัวอย่างที่การตัดสินใจด้านการออกแบบทิ้งความประทับใจไว้อย่างชัดเจน
เน้นการเรียนจากโค้ดเบสในงานจริง (crystal_revenge)
- คุณค่าการเรียนรู้สูงสุดมักมาจาก โค้ดเบสของทีมตัวเอง
- คุณจะได้เห็นทั้งทางเลือกที่ดีและไม่ดีผ่านกระบวนการเชื่อมโยงที่ สับสนและยุ่งเหยิง ระหว่างความต้องการจริงกับการอิมพลีเมนต์
- ข้อจำกัดในโลกจริงที่ใหญ่ที่สุดคือ แรงกดดันด้านเวลา และหัวใจสำคัญคือการเรียนรู้สมดุลระหว่างการออกแบบในอุดมคติกับความเป็นจริง
- ซอฟต์แวร์ที่ดีคือซอฟต์แวร์ที่ แก้ปัญหาความต้องการของผู้ใช้ได้ และประสบการณ์ที่ทำซ้ำจะช่วยให้เรียนรู้การออกแบบที่เพิ่มโอกาสสำเร็จ
ลิงก์ไปยังการถกเถียงและแหล่งข้อมูลเก่า (sprobertson)
- หัวข้อนี้ถูกพูดถึงใน HN หลายครั้งแล้ว
โค้ด vs เอกสารการออกแบบ (alphazard)
- โค้ดเบสเป็นเพียง ผลลัพธ์ของการอิมพลีเมนต์ ไม่ใช่ตัวการออกแบบเอง
- สำหรับการเรียนรู้การออกแบบ การ เขียนเอกสารการออกแบบ มีประสิทธิภาพมากกว่า
- เอกสารควรชัดเจนพอที่คนอื่นจะนำไปอิมพลีเมนต์ได้ตรงตามนั้น
- การลิสต์ทางเลือกและบันทึกว่าเหตุใดจึงไม่เลือกแต่ละทาง เป็น หลักฐานของการพิจารณาด้านการออกแบบ
- นักออกแบบที่ดีคือคนที่พิจารณา พื้นที่ของทางเลือกที่กว้างกว่า และเลือกจุดที่เหมาะสม
เน้นการเข้าใจทั้งระบบ (RossBencina)
- กระบวนการทำความเข้าใจทั้งโค้ดเบสมีคุณค่ามาก
- ไม่ใช่แค่ดูโค้ดที่ออกแบบดี แต่ยังเป็นการฝึกมอง ภาพรวมของระบบ
- การใช้ไดอะแกรมอย่าง UML เพื่อมองเห็นความสัมพันธ์จะช่วยได้
- แนวทางการเรียนรู้:
- การอ่านโค้ดของซอฟต์แวร์ที่คล้ายกับสิ่งที่คุณกำลังพัฒนาอยู่จะได้ผลดี
- แนะนำให้เริ่มจากโค้ดในโดเมนที่คุ้นเคยอยู่แล้ว (เว็บเฟรมเวิร์ก, เว็บเซิร์ฟเวอร์, Python standard library, VSCode ฯลฯ)
- ช่วงแรกควรเริ่มจากโปรแกรมเล็ก ๆ และโดเมนที่คุ้นเคย
เกณฑ์ของการออกแบบที่ดี (mamcx)
- การออกแบบที่ดีคือ เป้าหมายและแนวคิด ส่วนโค้ดเบสแสดงให้เห็น ระดับของการอิมพลีเมนต์มันออกมา
- การออกแบบที่ดีไม่ใช่แค่คำอธิบายอย่าง “เร็ว” หรือ “ปลอดภัย” แต่ต้องมี การพิจารณาอย่างเป็นรูปธรรมและการบันทึก trade-off
- ตัวอย่าง: Erlang, Pascal ยุคแรก, และการออกแบบของ RDBMS หลายตัว แสดงลักษณะนี้ได้ชัด
- ไลบรารีมาตรฐานของ Rust เน้นความปลอดภัยและความสม่ำเสมอ และทั้งโค้ดกับเอกสารก็สะท้อนสิ่งนี้ได้ดี จึงเป็นแหล่งเรียนรู้ที่ยอดเยี่ยม
การตัดสินใจด้านการออกแบบที่มองไม่เห็น (ben30)
- เมื่อดูโค้ดเบสที่ออกแบบดี ส่วนที่สำคัญที่สุดมักเป็นสิ่งที่มองไม่เห็น
- การตัดความซับซ้อนออก, การหลีกเลี่ยง abstraction ที่ไม่จำเป็น, การปฏิเสธบางแพตเทิร์น คือ การตัดสินใจผ่านสิ่งที่ไม่เลือกทำ ซึ่งสำคัญมาก
- วิธีเสริมคือใช้ ADR (Architectural Decision Records)
- เพื่อบันทึกทางเลือก เหตุผลที่ไม่เลือก และเหตุผลของทางเลือกที่เลือกไว้ ให้บริบทคงอยู่
- ช่วยทั้งผู้ดูแลในอนาคตและเครื่องมือ AI ได้มาก
- เวลาเรียนรู้ จึงควรดูไม่ใช่แค่โค้ด แต่รวมถึง โปรเจ็กต์ที่มีเอกสารการตัดสินใจด้านการออกแบบอย่าง ADR, RFC, PEP ควบคู่กันด้วย
ยังไม่มีความคิดเห็น