บทที่ 7: While You Are Coding (ระหว่างที่เขียนโค้ด)
4 min readภาพรวม
การเขียนโค้ดไม่ใช่กระบวนการทางกล (mechanical process): มันคือการตัดสินใจทุกนาทีที่ต้องใช้ความคิดและการตัดสินใจอย่างรอบคอบ บทนี้ครอบคลุมเทคนิคตั้งแต่การฟังสัญชาตญาณ ไปจนถึงการตั้งชื่อ ครอบคลุม 8 หัวข้อ
Topic 37: Listen to Your Lizard Brain (ฟังเสียงสมองส่วนสัตว์เลื้อยคลาน)
Tip 61: Listen to Your Inner Lizard: ฟังเสียงภายใน
เมื่อ intuition บอกว่ามีอะไรบางอย่างผิดปกติ ฟังมัน มันมักจะถูก สมองส่วนลึกของคุณรับรู้ pattern โดยที่คุณไม่รู้ตัว เมื่อรู้สึกว่าโค้ด "ไม่ถูก" หรือ design "ฝืน" ให้หยุดและตรวจสอบ
สิ่งที่ควรทำเมื่อสัญชาตญาณส่งสัญญาณ:
- หยุดสิ่งที่กำลังทำ
- สังเกตว่าความรู้สึกนั้นเกี่ยวกับอะไร: โค้ดส่วนไหน, design ส่วนไหน
- ถ้ามันรู้สึกผิด: มันอาจจะผิดจริง ๆ
Topic 38: Programming by Coincidence (การเขียนโปรแกรมด้วยความบังเอิญ)
Tip 62: Don't Program by Coincidence: อย่าเขียนโปรแกรมด้วยความบังเอิญ
Programming by coincidence คือการที่โค้ดทำงานได้, แต่คุณไม่รู้ว่า ทำไม มันถึงทำงาน คุณลองนั่นลองนี่จนมันทำงานโดยบังเอิญ นี่คือกับระเบิดรอเวลาที่จะระเบิดเมื่อเงื่อนไขเปลี่ยน
อาการของ programming by coincidence:
- ลองเพิ่มโค้ดบางอย่าง, มันทำงาน, ไม่ถามว่าทำไม
- assumption ที่ไม่ได้ตรวจสอบ
- "มันทำงานบนเครื่องฉันนี่นา"
- ติดตั้ง library โดยไม่รู้ว่ามันทำอะไร
ต้องรู้ว่า ทำไม โค้ดถึงทำงาน ไม่ใช่แค่ว่ามันทำงาน ถ้าไม่เข้าใจ หยุดและหาคำตอบก่อนเดินต่อ
Topic 39: Algorithm Speed (ความเร็วของอัลกอริทึม)
Tip 63: Estimate the Order of Your Algorithms: ประมาณ order ของอัลกอริทึม
Tip 64: Test Your Estimates: ทดสอบการประมาณของคุณ
Big-O Notation เป็นวิธีประมาณว่าเวลา/ทรัพยากรที่ใช้เพิ่มขึ้นอย่างไรเมื่อขนาด input เพิ่ม:
| Notation | ชื่อ | ตัวอย่าง |
|---|---|---|
| O(1) | Constant | เข้าถึง array element |
| O(log n) | Logarithmic | Binary search |
| O(n) | Linear | Sequential search |
| O(n log n) | Linearithmic | Quicksort (average) |
| O(n²) | Quadratic | Bubble sort |
| O(2ⁿ) | Exponential | Traveling salesman |
คำแนะนำ: ถ้าคุณมีลูปซ้อนกัน, alert! รู้ว่า Big-O ของโค้ดคุณคืออะไร, ทดสอบด้วยข้อมูลจริง, อย่า optimize โดยไม่วัดก่อน
Topic 40: Refactoring (การรีแฟกเตอร์)
Tip 65: Refactor Early, Refactor Often: รีแฟกเตอร์ตั้งแต่เนิ่น ๆ และบ่อย ๆ
Refactoring คือการปรับโครงสร้างโค้ดโดยไม่เปลี่ยนพฤติกรรมภายนอก: เป้าหมายคือทำให้โค้ด ETC (Easier To Change)
เมื่อไหร่ควร refactor:
- Duplication (DRY violation)
- Non-orthogonal design
- ความรู้ที่ล้าสมัย (requirements เปลี่ยน, ความเข้าใจ domain ดีขึ้น)
- Performance issues
- การผ่าน tests: นี่คือเวลาที่ดีที่สุด เพราะคุณมี safety net
หลักการ:
- อย่า refactor และเพิ่มฟีเจอร์พร้อมกัน
- มี good tests ก่อนเริ่ม refactoring
- ก้าวสั้น ๆ: เปลี่ยนทีละน้อยแล้ว test
Martin Fowler: "Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure."
Topic 41: Test to Code (ทดสอบระหว่างเขียนโค้ด)
Tip 66: Testing Is Not About Finding Bugs: การทดสอบไม่ใช่การหา bugs
Tip 67: A Test Is the First User of Your Code: test คือผู้ใช้คนแรกของโค้ดคุณ
Tip 69: Build End-to-End, Not Top-Down or Bottom-Up: สร้างแบบ end-to-end
Tip 70: Test Your Software, or Your Users Will: ทดสอบซอฟต์แวร์ของคุณ ไม่งั้นผู้ใช้จะทดสอบให้
Testing ไม่ใช่แค่การหา bugs, มันคือการได้ feedback ต่อ design, API, coupling ของคุณ ประโยชน์หลักของการทดสอบเกิดตอนที่คุณ คิดและเขียน tests, ไม่ใช่ตอนที่คุณ run มัน
Test-Driven Development (TDD): เขียน test ก่อนเขียนโค้ด test คือ specification ที่ executable ได้ มันบังคับให้คุณคิดเกี่ยวกับ interface ก่อน implementation
ประโยชน์ของการทดสอบ:
- ทำให้ coupling ชัดเจน: ถ้า test เขียนยาก แสดงว่าโค้ด coupled เกินไป
- เป็น documentation ที่ executable ได้
- ให้ความมั่นใจในการ refactor
Build tests เป็นส่วนหนึ่งของการสร้างซอฟต์แวร์: ไม่ใช่ phase ที่แยกออกมาต่างหาก
Topic 42: Property-Based Testing (การทดสอบแบบ property-based)
Tip 71: Use Property-Based Tests to Validate Your Assumptions
แทนที่จะเขียน test cases ด้วย input ที่คุณคิดเอง ให้คอมพิวเตอร์ generate input แบบสุ่มตาม constraints ที่คุณกำหนด, และตรวจสอบว่า properties (contracts, invariants) ของโค้ดยังคงเป็นจริง
ตัวอย่าง property: หลังจาก sort list: ความยาวต้องเท่าเดิม (invariant) และไม่มี element ใดมากกว่า element ถัดไป
ข้อดี:
- พบ assumptions ที่ผิดพลาดซึ่งคุณไม่เคยนึกถึง
- บังคับให้คุณคิดถึง invariants และ contracts: ทำให้ design ดีขึ้น
- ทดสอบ edge cases ที่คุณอาจมองไม่เห็น
เมื่อพบ bug: สร้าง unit test จาก parameters ที่ทำให้ fail: เพื่อเป็น regression test
Topic 43: Stay Safe Out There (อยู่อย่างปลอดภัย)
Tip 72: Keep It Simple and Minimize Attack Surfaces
Tip 73: Apply Security Patches Quickly
Security ไม่ใช่ feature, มันคือ mindset นักพัฒนาที่ careless คือสาเหตุของ data breaches เกือบทั้งหมด, ไม่ใช่เพราะแฮกเกอร์เก่ง
หลักการพื้นฐานด้านความปลอดภัย:
- Minimize Attack Surface Area: โค้ดซับซ้อน = attack vectors มากขึ้น, ข้อมูลจากภายนอกต้อง sanitize, authenticated/unauthenticated services ต้องคิดให้ดี, output data และ debugging info ก็เป็น attack vectors
- Principle of Least Privilege: ใช้สิทธิ์น้อยที่สุดเท่าที่จำเป็น: ในเวลาสั้นที่สุด
- Secure Defaults: ค่า default ต้องปลอดภัยที่สุด: ให้ผู้ใช้เลือกลดความปลอดภัยเอาเองถ้าต้องการ
- Encrypt Sensitive Data: อย่าเก็บ PII, passwords, credentials ใน plain text
- Maintain Security Updates: อัปเดต security patches ทันที: data breaches ครั้งใหญ่ที่สุดในประวัติศาสตร์เกิดจากระบบที่ไม่อัปเดต
กฎเหล็กของ cryptography: อย่าทำเอง: ใช้ libraries ที่ผ่านการตรวจสอบอย่างดีแล้วเท่านั้น
Password Antipatterns: อย่าจำกัดความยาวน้อยกว่า 64 ตัวอักษร, อย่า disable paste, อย่าบังคับเปลี่ยนรหัสผ่านโดยไม่มีเหตุ, อย่าบังคับ composition rules (ตัวใหญ่/เล็ก/ตัวเลข/พิเศษ)
Topic 44: Naming Things (การตั้งชื่อ)
Tip 74: Name Well; Rename When Needed
ชื่อมีความสำคัญอย่างยิ่ง สมองมนุษย์อ่านและเข้าใจคำได้เร็วกว่ากิจกรรมอื่น ๆ (Stroop Effect) ดังนั้นชื่อที่ดีช่วยให้เข้าใจโค้ดได้เร็วขึ้น
หลักการตั้งชื่อ:
- ตั้งชื่อตามบทบาท (role) ที่สิ่งนั้นเล่นในโค้ด: ไม่ใช่แค่สิ่งที่มันทำ
- ถามตัวเอง: "แรงจูงใจในการสร้างสิ่งนี้คืออะไร?"
- ใช้ชื่อที่เฉพาะเจาะจง:
buyerแทนuser,applyDiscountแทนdeductPercent - ใช้ types เพื่อสื่อความหมาย:
Percentageแทนdouble - Honor the culture: ใช้ convention ของภาษานั้น ๆ:
i,j,kในภาษา C เป็นที่ยอมรับ แต่ใน Clojure ไม่ใช่ - Consistency: ใช้คำศัพท์เดียวกันทั่วทั้งโปรเจกต์: สร้าง project glossary
- เมื่อความหมายเปลี่ยน, เปลี่ยนชื่อทันที, อย่าปล่อยให้มี misleading names