กับดักของความฉลาด: ทำไมโค้ดที่ "เรียบง่าย" ถึงชนะเสมอในโลกการทำงาน
เวลาเราเริ่มฝึกเขียนโปรแกรมใหม่ๆ เรามักจะตื่นเต้นกับการค้นพบวิธีเขียนโค้ดที่ดูฉลาด หรือการใช้เทคนิคใหม่ๆ ที่ทำให้โค้ดสั้นลงจนน่าทึ่ง มันเหมือนกับการได้เล่นเกมไขปริศนาที่ยิ่งเราแก้โจทย์ยากๆ ได้สวยเท่าไหร่ เราก็ยิ่งรู้สึกภูมิใจมากเท่านั้น แต่ในโลกของ Backend Engineer (วิศวกรผู้ดูแลระบบหลังบ้าน) ความฉลาดที่มากเกินไปมักจะมีราคาที่ต้องจ่ายเสมอ
ความซับซ้อนที่ดูเท่ในวันนี้ อาจกลายเป็นฝันร้ายเมื่อคุณต้องมาแก้บั๊ก (ข้อผิดพลาดของโปรแกรม) ตอนตีสาม เพราะโค้ดที่เขียนไว้ดูอ่านยากจนไม่มีใครเข้าใจว่ามันทำงานอย่างไรจริงๆ การเขียนโค้ดให้สั้นหรือใช้ Abstraction (การซ่อนรายละเอียดที่ซับซ้อนไว้ในกล่องดำ) จนเกินพอดี ไม่ใช่การก้าวหน้า แต่เป็นการสร้างภาระให้คนอื่นในอนาคต
บทความนี้จะพาคุณไปทำความเข้าใจว่าทำไม Strategic Simplicity (ความเรียบง่ายเชิงกลยุทธ์) ถึงเป็นทักษะที่สำคัญที่สุดของโปรแกรมเมอร์มืออาชีพ เราจะมาดูกันว่าความฉลาดที่มากเกินไปส่งผลกระทบอย่างไร และทำอย่างไรให้โค้ดของคุณทั้งทำงานได้ดีและอ่านเข้าใจง่ายสำหรับทุกคนในทีม
ความฉลาดมีราคาที่ต้องจ่ายเสมอ
ทุกครั้งที่เราตัดสินใจเขียนโค้ดด้วยตรรกะที่ซับซ้อนหรือใช้เครื่องมือที่ดูเหนือชั้น เรากำลังกู้ยืมความสะดวกสบายจากอนาคตมาใช้ในปัจจุบัน คุณอาจจะภูมิใจที่ยุบโค้ด 200 บรรทัดเหลือเพียง 15 บรรทัดด้วยการใช้เทคนิคที่ลึกซึ้ง แต่เมื่อเวลาผ่านไป เพื่อนร่วมงานของคุณต้องมานั่งแกะโค้ดนั้นภายใต้แรงกดดัน นั่นแหละคือเวลาที่ "ใบแจ้งหนี้" ของความฉลาดจะถูกส่งมาถึง
ลองจินตนาการถึงการเดินเข้าไปในห้องสมุดที่ทุกอย่างถูกจัดวางด้วยระบบรหัสลับที่คุณต้องเป็นคนเขียนคู่มือเองถึงจะหาหนังสือเจอ ในการเขียนโปรแกรมก็เช่นกัน โค้ดที่ฉลาดมักจะแก้ปัญหาหนึ่งโดยการสร้างปัญหาใหม่ขึ้นมาอีกสามอย่างโดยไม่รู้ตัว เราเสียความชัดเจน (Clarity) และเสียความง่ายในการตรวจสอบไปเพียงเพื่อแลกกับความเท่ชั่วคราว
เราไม่ได้บอกว่าความฉลาดเป็นเรื่องเลวร้าย แต่ในงานส่วนใหญ่ของ Backend ที่ต้องจัดการกับ API (ช่องทางเชื่อมต่อระหว่างโปรแกรม) หรือการจัดการข้อมูลทั่วไป ความเรียบง่ายมีค่ามากกว่าความหรูหรา หากระบบของคุณไม่ได้กำลังทำเรื่องที่ซับซ้อนระดับโลก การเลือกวิธีที่ตรงไปตรงมาที่สุดคือทางเลือกที่ฉลาดที่สุดในระยะยาว
// ตัวอย่าง: การเขียนโค้ดแบบ "ฉลาด" เกินความจำเป็น
const processData = (d) => d?.map(x => x.v).filter(Boolean).reduce((a, b) => a + b, 0);
// คำอธิบาย: โค้ดนี้สั้นมาก แต่คนมาอ่านทีหลังต้องใช้เวลาคิดว่า d คืออะไร และ x.v คืออะไร
// ถ้าข้อมูลผิดพลาด จะหาที่มาของบั๊กยากมากเพราะทุกอย่างรวมอยู่ในบรรทัดเดียว
บรรทัดที่ 2 คือการใช้ฟังก์ชัน map (การวนลูปเปลี่ยนค่าในรายการ), filter (การกรองข้อมูล) และ reduce (การยุบข้อมูลรวมกัน) ซึ่งดูเหมือนโปรแกรมเมอร์มือโปร แต่ผลลัพธ์คือโค้ดที่อ่านยาก หากข้อมูลใน d ไม่มีค่า v โปรแกรมอาจจะพังโดยไม่บอกสาเหตุ ทำให้การไล่ลำดับการทำงาน (Debug) เป็นเรื่องยาก
เมื่อความตั้งใจดีกลายเป็นความซับซ้อนที่เกินพอดี
ปัญหาของความซับซ้อนมักเริ่มจากความตั้งใจที่ดีเสมอ เราอยากให้ระบบมีความยืดหยุ่น (Flexibility) อยากให้รองรับการขยายตัว (Scale) ในอนาคตที่ยังมาไม่ถึง เราจึงสร้างโครงสร้างที่ซับซ้อนเกินความจำเป็นไปมาก ผลลัพธ์คือระบบที่เตรียมพร้อมสำหรับทุกอย่าง ยกเว้นสิ่งที่มันต้องทำจริงๆ ในทุกวันนี้
บ่อยครั้งที่งานง่ายๆ อย่างการบันทึกข้อมูลผู้ใช้ถูกขยายจนกลายเป็นระบบที่มีลำดับชั้นมากมาย มีการส่งต่อข้อมูลผ่านหลายขั้นตอนจนคุณเองยังจำไม่ได้ว่าจุดเริ่มต้นอยู่ที่ไหน นี่คือสิ่งที่เรียกว่า Over-engineering (การออกแบบระบบให้ซับซ้อนเกินความต้องการจริง) ซึ่งทำให้ทีมต้องเสียเวลากับการบำรุงรักษามากกว่าการสร้างฟีเจอร์ใหม่
การฝึกเป็นโปรแกรมเมอร์ที่ดีไม่ใช่การสร้างระบบที่รองรับทุกอย่าง แต่คือการสร้างระบบที่ เปลี่ยนได้ง่าย เมื่อมีความต้องการใหม่เข้ามา การเขียนโค้ดที่เรียบง่ายช่วยให้คุณและทีมงานอ่านโค้ดแล้วรู้ทันทีว่าส่วนไหนทำอะไร โดยไม่ต้องเปิดไฟล์ไล่ดูเป็นสิบๆ ไฟล์เพื่อทำความเข้าใจตรรกะพื้นฐาน
// ตัวอย่าง: การเขียนโค้ดที่ "เรียบง่าย" และตรงไปตรงมา
function calculateTotal(items) {
let total = 0;
for (const item of items) {
if (item.value) {
total += item.value;
}
}
return total;
}
// คำอธิบาย: โค้ดนี้ยาวกว่าแบบแรก แต่ใครอ่านก็เข้าใจได้ทันทีว่ากำลังบวกเลขจากรายการ
// ถ้าเกิดบั๊ก เราสามารถใส่ console.log() เพื่อดูค่าแต่ละรอบได้ง่ายมาก
ผลลัพธ์ที่ได้คือ total ของรายการที่ส่งเข้ามา หากรันโค้ดนี้ด้วย calculateTotal([{value: 10}, {value: 20}]) จะได้ค่ากลับมาเป็น 30 ซึ่งชัดเจนและตรวจสอบได้ง่ายกว่าแบบแรกมาก
ต้นทุนที่แท้จริงคือเรื่องของคน ไม่ใช่เครื่องจักร
เรามักจะพูดถึงต้นทุนของเครื่องจักร เช่น การใช้ CPU (หน่วยประมวลผล) หรือ Memory (หน่วยความจำ) แต่มักลืมต้นทุนที่แพงที่สุดไป นั่นคือ ต้นทุนของมนุษย์ โปรแกรมเมอร์คนใหม่ในทีมต้องใช้เวลานานแค่ไหนกว่าจะแก้ไขโค้ดนี้ได้โดยไม่ทำระบบพัง การทำงานกับทีมคือการสื่อสารผ่านโค้ด ถ้าโค้ดของคุณอ่านยาก เพื่อนร่วมทีมก็ทำงานลำบาก
ระบบที่ซับซ้อนเกินไปมักจะสร้าง "ฮีโร่" ขึ้นมาในทีม คือคนที่เข้าใจระบบอยู่คนเดียวคนเดียว ถ้าคนๆ นั้นลาพักร้อน ทั้งทีมก็จะเกิดความกังวล นี่ไม่ใช่สัญญาณของการออกแบบระบบที่ดี แต่เป็นสัญญาณของระบบที่มี Single Point of Failure (จุดเปราะบางที่ถ้าพังจะทำให้ทั้งระบบล่ม) ที่สวมแว่นตาทำงานอยู่
เมื่อคุณหัดเขียนโปรแกรม ให้จำไว้ว่าโค้ดที่ดีคือโค้ดที่คนอื่นอ่านรู้เรื่อง การเขียนให้อ่านง่ายคือการให้เกียรติเพื่อนร่วมงานและให้เกียรติตัวเองในอนาคตด้วย หากคุณสามารถอธิบายให้เด็กฝึกงานเข้าใจได้ว่าโค้ดส่วนนี้ทำงานอย่างไร นั่นคือชัยชนะที่ยิ่งใหญ่กว่าการเขียนโค้ดที่ดูฉลาดแต่ไม่มีใครเข้าใจ
การแก้บั๊กคือเครื่องพิสูจน์ความจริง
เวลาที่ทุกอย่างดูปกติ โค้ดที่ฉลาดจะดูน่าประทับใจมาก แต่เมื่อเกิดเหตุการณ์ Production down (ระบบที่ใช้งานจริงพัง) ความกดดันจะเข้ามาแทนที่ ในตอนนั้น คุณไม่ต้องการความสวยงามของโค้ด คุณต้องการแค่ความชัดเจนว่าบั๊กอยู่ที่ไหนและจะแก้ไขอย่างไรให้เร็วที่สุด
ถ้าโค้ดของคุณถูกซ่อนไว้ใต้ Abstraction Layers (ชั้นของการห่อหุ้มที่ซับซ้อน) หลายชั้น การไล่หาต้นตอของปัญหาจะเป็นเรื่องที่ทรมานมาก คุณจะเสียเวลาไปกับการทำความเข้าใจว่าโค้ดมันทำงานยังไง มากกว่าการแก้ปัญหาจริงๆ การเขียนโค้ดที่เรียบง่ายจะช่วยให้คุณรักษาความสงบในใจได้แม้ในสถานการณ์ที่หน้าจอ Dashboard ของทีมกำลังกลายเป็นสีแดง
จำไว้ว่าเครื่องจักรไม่มีความรู้สึก มันรันโค้ดที่อ่านยากได้ดีพอๆ กับโค้ดที่อ่านง่าย แต่คนเราไม่ใช่แบบนั้น เมื่อคุณต้องแก้ปัญหาภายใต้ความกดดัน โค้ดที่ตรงไปตรงมาคือเพื่อนที่ดีที่สุดของคุณ การเขียนโค้ดที่เรียบง่ายจึงไม่ใช่เรื่องของความอ่อนหัด แต่เป็นเรื่องของความมีวินัย (Discipline) ของมืออาชีพ
บทสรุป: เริ่มต้นด้วยความเรียบง่าย
การเป็นโปรแกรมเมอร์ที่เก่งไม่ได้วัดกันที่ว่าคุณใช้เทคนิคที่ซับซ้อนแค่ไหน แต่วัดกันที่ว่าคุณแก้ปัญหาให้ธุรกิจได้ดีเพียงใดโดยที่คนในทีมยังทำงานร่วมกันได้มีความสุข การเลือกความเรียบง่ายคือการเลือกทางที่ยากที่สุด เพราะมันต้องใช้การคิดวิเคราะห์ให้ดีก่อนจะลงมือเขียน เพื่อให้ได้สิ่งที่ง่ายที่สุดสำหรับทุกคน
หากวันนี้คุณกำลังฝึกเขียนโปรแกรม ลองทำตามกฎเหล็กนี้: "ถ้าอธิบายให้เพื่อนฟังไม่ได้ว่าโค้ดบรรทัดนี้ทำอะไร ให้เขียนใหม่ให้ง่ายกว่าเดิม" การฝึกแบบนี้จะทำให้คุณกลายเป็นโปรแกรมเมอร์ที่ใครๆ ก็อยากร่วมงานด้วย และที่สำคัญที่สุด คือคุณจะมีความสุขกับการเขียนโค้ดในระยะยาว
ลองนำแนวคิดนี้ไปใช้กับโปรเจกต์ถัดไปที่คุณทำ ถ้าคุณพบว่าตัวเองเริ่มสร้างโครงสร้างที่ซับซ้อนเกินไป ให้หยุดและถามตัวเองว่า "มีวิธีที่ง่ายกว่านี้ไหม" ความเรียบง่ายคือจุดสูงสุดของความซับซ้อน และมันคืออาวุธที่ทรงพลังที่สุดที่คุณจะมีในฐานะโปรแกรมเมอร์มืออาชีพ
ที่มา: The Cost of Cleverness: A Backend Engineer’s Guide to Strategic Simplicity — DEV Community