1 คะแนน โดย GN⁺ 2025-08-30 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในการออกแบบซอฟต์แวร์ การเลือก “สิ่งที่เรียบง่ายที่สุดเท่าที่เป็นไปได้” อยู่เสมอเป็นคำแนะนำที่ได้ผล
  • การออกแบบระบบที่ยอดเยี่ยมมักไม่ได้ดูยิ่งใหญ่อลังการ แต่แก้ปัญหาได้ด้วยองค์ประกอบให้น้อยที่สุดเท่าที่จำเป็น
  • เมื่อตามหาวิธีแก้ที่เรียบง่าย สามารถยึดหลัก YAGNI(You Aren't Gonna Need It) เป็นปรัชญาหลักในการออกแบบ โดยค่อย ๆ ขยายเมื่อมีความต้องการใหม่เกิดขึ้นจริงเท่านั้น
  • แม้จะมีข้อถกเถียงเรื่องนิยามของ “ความเรียบง่าย” แต่ระบบที่มีคอมโพเนนต์น้อย การเชื่อมต่อภายในหลวม และมีเสถียรภาพ คือสิ่งที่ใกล้เคียงความเรียบง่ายที่สุด
  • การหมกมุ่นกับความสามารถในการขยายระบบมากเกินไปทำให้โค้ดเบสขาดความยืดหยุ่น ดังนั้นการออกแบบที่เรียบง่ายและยึดตามความต้องการจริงจึงได้เปรียบกว่าในระยะยาว

การแสวงหาสิ่งที่เรียบง่ายที่สุดเท่าที่เป็นไปได้

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

ความเรียบง่ายที่มักถูกประเมินต่ำไป

  • การออกแบบระบบต้องอาศัยความสามารถในการใช้เครื่องมือหลากหลาย เช่น app server, proxy, database, cache, queue เป็นต้น
  • ยิ่งเป็นวิศวกรระดับจูเนียร์ ยิ่งอยากใช้หลายเทคโนโลยีเพื่อสร้างโครงสร้างที่ซับซ้อน แต่ความชำนาญที่แท้จริงกลับอยู่ที่การตัดสิ่งไม่จำเป็นออก
  • การออกแบบซอฟต์แวร์ที่ยอดเยี่ยมมักดูธรรมดาเสียจนให้ความรู้สึกว่า ปัญหานั้นแก้ได้ง่ายกว่าที่คิด
  • ตัวอย่างเช่น Unicorn และ Rails REST API อาศัยความสามารถพื้นฐานของ Unix เพื่อให้ได้ โครงสร้างน้อยที่สุด พร้อมรับประกันคุณสมบัติหลักต่าง ๆ (การแยกส่วน การขยายระบบ การกู้คืน ฯลฯ) จึงถือว่าเป็นการออกแบบที่ยอดเยี่ยม

วิธีคิดในการทำให้เรียบง่าย

  • ตัวอย่างเช่น เมื่อเพิ่มฟีเจอร์ rate limiting ให้กับแอปพลิเคชัน Golang อาจใช้ external storage อย่าง Redis ได้ แต่ถ้ายังไม่จำเป็นจริง ก็อาจลองวิธีที่เรียบง่ายกว่าก่อน เช่น การนับในหน่วยความจำ
  • หากวิธีที่เรียบง่ายเพียงพอ ก็สามารถเลื่อนการเพิ่มโครงสร้างพื้นฐานที่หนักออกไปก่อนได้
  • ทำให้สามารถค่อย ๆ พัฒนาขยายระบบได้เมื่อมีความต้องการใหม่เกิดขึ้นจริงเท่านั้น
  • นี่คือแนวทางที่ให้หลัก YAGNI เป็นลำดับความสำคัญสูงสุดในการออกแบบ

กับดักของความเรียบง่ายและข้อจำกัดในโลกจริง

1. ปรากฏการณ์ Big Ball of Mud

  • หากพยายามแก้ทุกความต้องการแบบเฉพาะหน้า ก็เสี่ยงที่โค้ดเบสจะกลายเป็น “ก้อนโคลนขนาดใหญ่(big ball of mud)” ที่ซับซ้อนและดูแลรักษายาก
  • แต่การแก้แบบฉาบฉวย (hack) ไม่ใช่ความเรียบง่าย ตรงกันข้าม มันเพิ่มความซับซ้อนให้การทำความเข้าใจและการบำรุงรักษา
  • การจะหาวิธีแก้ที่เรียบง่ายจริง ๆ ต้องเปรียบเทียบหลายแนวทางและทำ วิศวกรรมอย่างเป็นระบบ อย่างแท้จริง

2. นิยามของความเรียบง่าย

  • ไม่ใช่เรื่องง่ายที่จะเห็นตรงกันว่า “ความเรียบง่าย” คืออะไร
  • โดยทั่วไป ระบบที่เรียบง่ายคือระบบที่มี ชิ้นส่วนที่เคลื่อนไหว(องค์ประกอบการทำงาน) น้อย, การเชื่อมต่อระหว่างคอมโพเนนต์หลวม, และ มีอินเทอร์เฟซที่ชัดเจน
  • ตัวอย่างจริง: Unix process และ Unicorn ไม่ได้แชร์หน่วยความจำกัน จึงมีความเรียบง่ายสูง และเมื่อเทียบกับ Puma หรือ Redis ก็มีการเชื่อมโยงภายในต่ำกว่า
  • เมื่อเลือกได้ยาก ให้มองว่า สิ่งที่ต้องดูแลรักษาน้อยกว่า คือสิ่งที่เรียบง่ายกว่า

3. คำวิจารณ์ต่อการหมกมุ่นกับ scalability

  • “วิธีที่เรียบง่าย” อาจไม่เหมาะกับทราฟฟิกขนาดใหญ่
  • แต่การออกแบบให้ซับซ้อนล่วงหน้าเพื่อรองรับการขยายขนาดอย่างรุนแรงในอนาคต ส่วนใหญ่มักเป็นความพยายามที่ไร้ประโยชน์
  • โค้ดส่วนใหญ่ในความเป็นจริง แค่เตรียมรับทราฟฟิกที่เพิ่มขึ้นราว 2–5 เท่าก็เพียงพอ และหากเกินกว่านั้น การค่อยรับมือเมื่อเกิดปัญหาจริงย่อมสมเหตุสมผลกว่า
  • การออกแบบที่ยึด scalability มากเกินไปทำลายความยืดหยุ่นของโค้ด การแยกโครงสร้างมากเกินความจำเป็นกลับทำให้การพัฒนาฟังก์ชันบางอย่างยากขึ้น และอาจต้องจัดการ transaction ที่ซับซ้อนตามมาด้วย

บทสรุป

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

ภาคผนวก: ที่มาของคำศัพท์และการถกเถียงใน Hacker News

  • ต่อความเห็นที่ว่าสถาปัตยกรรมแบบเรียบง่ายจะยิ่งหมดความหมายเมื่อระบบมีขนาดใหญ่ขึ้น ผู้เขียนกลับยืนยันว่า ยิ่งเป็นระบบขนาดใหญ่ โครงสร้างที่เรียบง่ายยิ่งสำคัญกว่าเดิม (เพื่อรับมือกับความซับซ้อนจากปฏิสัมพันธ์ระหว่างฟีเจอร์)
  • วลี “Do the simplest thing that could possibly work” ถูกบัญญัติขึ้นโดย Ward Cunningham และ Kent Beck

1 ความคิดเห็น

 
GN⁺ 2025-08-30
ความคิดเห็นจาก Hacker News
  • ฉันคิดว่าแนวทางแบบนี้ใช้ได้ดีกับโดเมนที่เรียบง่าย แต่ถึงอย่างนั้นหลังจากทำงานในบริษัทเทคขนาดใหญ่มานานก็ยังรู้สึกประหลาดใจกับความซับซ้อนที่ต้องรองรับอยู่เสมอ แม้แต่ปัญหาทางธุรกิจที่ดูง่ายที่สุดก็อาจใช้เวลามากกว่าหนึ่งปีกว่าจะแก้ได้ หรือพังบ่อยจาก edge case จำนวนมากและปัญหาเรื่องสเกล คนที่ชูเรื่องความเรียบง่ายอาจไม่เคยมีประสบการณ์กับระบบขนาดใหญ่ ต่อให้ดูโค้ดเบสอายุ 10 ปี ก็ยังมีสิ่งที่ต้องคำนึงถึงมากเกินไปจนการ rewrite มักล้มเหลวอยู่บ่อย ๆ เหมือนอุปมา Chesterton's Fence ถ้าไม่รู้เหตุผลที่บางสิ่งมีอยู่ ก็ต้องมีปัญญาพอที่จะไม่ลบมันทิ้งส่งเดช

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

    • อย่างที่ชี้ไว้ ความซับซ้อนอาจไม่ได้มาจากตัวโดเมนเองเสมอไป แต่อาจเป็นปัญหาที่เกิดจากการออกแบบซอฟต์แวร์ที่ไม่ดี ถ้าเต็มไปด้วย dependency และ side effect ก็แปลว่าการแยก concerns กับการจัดการ coupling ทำได้ไม่ดี การ refactor จะแทบเป็นไปไม่ได้ และถ้าวัฒนธรรมองค์กรไม่ดีขึ้น ระหว่าง refactor ก็จะมีแต่ปัญหาใหม่ถูกแปะเพิ่มเข้าไปเรื่อย ๆ ถึงอย่างนั้น แค่การแยก concerns และการประกอบแบบเรียบง่ายก็ยังช่วยแก้ปัญหาซับซ้อนได้ แม้จะยาก แต่ถ้า senior developer มีมุมมองนี้อย่างมั่นคง โอกาสสำเร็จก็จะสูงขึ้น

    • มีคนพูดถึงว่าผู้เขียนเป็น staff engineer ของ GitHub ดังนั้นฉันคิดว่าคนนี้ก็น่าจะมีประสบการณ์กับระบบขนาดใหญ่เพียงพอ

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

    • ที่ทำงานก่อนหน้านี้ ความซับซ้อนส่วนใหญ่เกิดจากความพยายาม refactor หรือปรับปรุงที่ล้มเหลว ถูกยกเลิกกลางทาง หรือทำไม่เสร็จ ฉันมักสงสัยว่าถ้าป้องกันสิ่งเหล่านี้ได้ตั้งแต่ต้น เราจะได้รับมอบระบบที่เรียบง่ายกว่านี้หรือเปล่า ไม่ได้หมายความว่าไม่ควร refactor หรือปรับปรุงเลย แต่คิดว่าควรวางแผนให้ครอบคลุม use case 100% อย่างชัดเจน และต้องมีงบกับ milestone พร้อม เพื่อให้แน่ใจว่าจะค่อย ๆ ปรับปรุงได้จริง

  • อยากให้มีการระบุที่มาของวลี "สิ่งที่ง่ายที่สุดเท่าที่จะเป็นไปได้" ให้ชัดเจนหน่อย วลีนี้เป็นหลักการที่ Ward Cunningham ผู้คิดค้น wiki และ Kent Beck ใช้กันบ่อยช่วงปลายยุค 80 ตอนที่ทำงานร่วมกัน ทั้งคู่คอยเตือนกันถึงหลักการนี้ระหว่างเขียนโค้ด และต่อมากลายเป็นหัวข้อสำคัญในการพูดและการเขียน อย่างตัวอย่างประตูปิดที่บทความนี้ยกมา มันดูเรียบง่าย แต่ "ความเรียบง่าย" นั้นก็เปลี่ยนไปตามสถานการณ์ บทความนี้ก็พูดถึงจุดนั้นเหมือนกัน คือการหาวิธีแก้ที่เรียบง่ายไม่ได้เรียบง่ายเสมอไป พวกเขาก็รู้ตัวว่าวิธีนี้อาจทิ้งหนี้เทคนิคไว้ แต่ลำดับความสำคัญคือทำให้โค้ดทำงานก่อน ส่วนตัวฉันอยากให้บทความนี้พูดถึงมุมของหนี้เทคนิคมากกว่านี้อีกหน่อย

    • หลังจากนั้น Kent Beck ก็ทำให้ Extreme Programming กลายเป็นแนวทางอย่างเป็นทางการ ซึ่งเป็นชุดของแนวปฏิบัติที่ช่วยให้ระบบเรียบง่ายค่อย ๆ วิวัฒน์ได้ตามการเปลี่ยนแปลงของ requirement

    • ฉันเคยได้ยินวลีนี้จากเพื่อนร่วมงานและเห็นเขาใช้เป็นเหมือนคติประจำชีวิต แต่ไม่รู้เลยว่า Ward Cunningham เป็นต้นฉบับ พอคำนี้ถูกใช้แพร่หลายมากจนไม่มีใครรู้ว่าใครเป็นคนคิด นั่นก็ดูเหมือนเป็นเกียรติสูงสุดแบบหนึ่ง

    • น่าสนใจที่มีการพูดถึง Wiki ที่ทำงานเก่าของฉันใช้ Lotus Notes จัดการโปรเจกต์ ซึ่งมีประโยชน์มากเพราะมันไฮไลต์ให้เห็นเลยว่าเอกสารถูกเปลี่ยนเมื่อไร โปรเจกต์ถัดมาใช้แต่ Wiki อย่างเดียว แต่กลับมองไม่ออกเลยว่าเอกสารไหนเปลี่ยนไปบ้าง จนแทบใช้งานอะไรไม่ได้ มันเรียบง่ายก็จริง แต่เรียบง่ายเกินไปจนใช้งานจริงไม่สะดวก

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

    • ช่วงที่ยากที่สุดในอาชีพของฉันคืออยู่ในบริษัทที่มีทีมหนึ่งชอบทำ prototype ทีมนี้จะทำแค่ proof of concept อย่างรวดเร็ว เดโมให้ผู้บริหารดู แล้วก็ปล่อยขึ้นระบบทันที จากนั้นผู้บริหารก็เข้าใจผิดว่าถ้าทำเสร็จเร็วขนาดนี้ก็น่าจะ deploy ได้เลย แต่พอทีมที่ต้องรับช่วงต่อเปิดโค้ดดู ก็พบว่าสิ่งจำเป็นอย่าง end-to-end security, validation, error handling และอื่น ๆ หายไปหมด สุดท้ายต้องสร้างใหม่ตั้งแต่ต้น และผู้บริหารก็เข้าใจผิดอีกว่าทีม deploy กำลังทำอะไรให้ซับซ้อนเกินเหตุ

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

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

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

  • ความย้อนแย้งของคำแนะนำแบบนี้คือ คนที่นำไปใช้ได้ดีจริง ๆ มักเป็นผู้เชี่ยวชาญที่มีประสบการณ์มากอยู่แล้ว เช่น จะรู้ได้อย่างไรว่าสิ่งไหนคือ "สิ่งที่ง่ายที่สุด" หรือจะตัดสินอย่างไรว่ามันใช้ได้จริง ไม่นานมานี้ฉันทำ XLSX importer เอง แล้วพลาดเรื่องการจัดการ XML namespace เพราะดันสมมติว่า Excel จะใช้แต่ default namespace เสมอ พอทีหลังได้รับไฟล์ที่ใช้ namespace แบบอื่นก็พังทันที ถ้าจะทำแบบง่าย ๆ ก็แค่ลบ prefix ทิ้งแล้วประมวลผล แต่เพื่ออนาคตของตัวเอง ฉันเลยใช้เวลา 4 ชั่วโมงเขียน parser ใหม่ทั้งชุดให้รองรับ namespace อย่างถูกต้อง การจะทำ "สิ่งที่ง่ายที่สุด" จริง ๆ ไม่ได้ง่ายขนาดนั้น และยิ่งมีประสบการณ์ก็ยิ่งตัดสินได้ดีขึ้น แต่พอมีประสบการณ์ถึงระดับนั้นแล้ว ก็รู้สึกเหมือนไม่จำเป็นต้องมีคำแนะนำแบบนี้อีกแล้วเหมือนกัน

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

    • ที่บริษัทเราใช้หลักว่า "อย่าเพิ่มโค้ดไปในทิศทางที่ผิด" ต่อให้เป็นการ implement แค่บางส่วน ก็ต้องเขียนในแนวทางที่ต่อยอดภายหลังได้ดี นี่คือ KISS แต่ไม่ยอมรับทางลัดเด็ดขาด

    • ฉันตัดสินความเรียบง่ายจาก "สิ่งที่เปลี่ยนผ่านได้ง่ายที่สุด" บริการเดี่ยวที่ไม่พึ่ง abstraction หรือ infrastructure ซับซ้อนมากนัก สุดท้ายมักเปลี่ยนผ่านได้ง่ายกว่า คนที่เข้ามาอ่านก็เข้าใจได้ทันที และทั้งการส่งต่องานกับการ debug ก็ทำได้สะดวกกว่า แต่ถ้าจำเป็นต้องมี abstraction ก็ใส่ และถ้าจำเป็นต้องมี infrastructure ก็เพิ่ม สิ่งสำคัญคือ เวลาส่งมอบโค้ด ฉันจะคิดเสมอว่าโครงสร้างนี้อธิบายได้ง่ายที่สุดหรือยัง เมื่อก่อนฉันเคยพยายามทำทุกอย่างให้เป็น abstraction แยกตาม service ตั้งค่าได้หมด และแทบไม่มีโค้ดเลย แต่ในทางปฏิบัติการเปลี่ยนผ่านและการส่งต่องานล้มเหลวโดยสิ้นเชิง ตอนนี้เลยทำให้โครงสร้างซับซ้อนเฉพาะเมื่อจำเป็นจริง ๆ และให้ค่าเริ่มต้นเป็นความเรียบง่ายที่เข้าใจได้ทันที ซึ่งสุดท้ายก็เป็นประโยชน์ทั้งต่อการ onboarding คนใหม่ การแก้บั๊ก และการเปลี่ยนผ่านจริง

    • AI vibecoding ก็คล้ายกัน ยิ่งมีประสบการณ์และ know-how มากขึ้น ก็ยิ่งเลือก task ที่เหมาะสมและบริหาร agent ได้ง่ายขึ้น

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

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

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

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

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

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

    • ฉันเห็นด้วยกับข้อโต้แย้งของคุณ แต่ก็อยากชี้ว่าท้ายที่สุดแล้วมันมักกลับไปจบที่ "ทุกอย่างคือ trade-off" หรือ "ไม่มีของฟรี" อยู่ดี หลักการทั่วไปทั้งหลายเป็นการสรุปประสบการณ์ภาคสนามจำนวนมาก จึงตัดทิ้งไปเสียหมดไม่ได้ ปัญหาคือเมื่อคอนเซปต์ที่ใช้งานได้จริงค่อย ๆ กลายเป็นข่าวลือเกินจริงหรือเป็นลัทธิ จนสุดท้ายเหลือแค่การถกเถียงเรื่องชื่อโฟลเดอร์

  • จากการสร้างระบบ 0-1 หลายระบบในสตาร์ตอัปช่วง Seed ถึง Series C ฉันซึมซับหลักการหนึ่งมาอย่างลึกซึ้งว่า "ความเรียบง่ายคือความแข็งแกร่ง" ทั้งการออกแบบเริ่มต้นและการปรับปรุงระบบเดิม ล้วนเผลอออกแบบเกินความจำเป็นได้ง่าย ความต้องการของลูกค้าพัฒนาอยู่ตลอด และต่อให้พยายามคาดการณ์ความต้องการในอนาคตอย่างไร สุดท้ายก็ย่อมพลาดอยู่ดี ฉันคิดว่าความเรียบง่ายไม่ได้แค่ลดข้อผิดพลาด แต่ยังเป็นฐานให้เปลี่ยนโครงสร้างได้ง่ายด้วย ควรเตรียม X, Y, Z ที่เป็นไปได้ไว้ แต่ยังคงมุ่งไปที่การสร้าง "สิ่งที่ง่ายที่สุด" เพื่อเผื่อทางเลือกและการขยายในอนาคต ความซับซ้อนย่อมเพิ่มข้อจำกัดโดยหลีกเลี่ยงไม่ได้ และยิ่งกองสะสมตามเวลา สแต็กก็ยิ่งอ่อนแอลง

  • ฉันคิดว่าต้องเคยลองออกแบบ "ระบบในอุดมคติ" มาระดับหนึ่งก่อน ถึงจะไปถึง "สิ่งที่ง่ายที่สุด" ได้ การสร้างระบบที่อ่านง่ายและเปลี่ยนแปลงได้ง่ายต้องอาศัย know-how มากเหมือนกัน แม้แต่การปรับปรุงที่ "เรียบง่าย" อย่างแท้จริงก็มาจากประสบการณ์และความเข้าใจอย่างลึกซึ้ง

  • นี่สอดคล้องกับ Gall's law ตามทฤษฎีนี้ ระบบที่ซับซ้อนและทำงานได้จริง มักเริ่มจากระบบง่าย ๆ ก่อน แล้วค่อย ๆ เพิ่มความซับซ้อนเข้าไป ระบบที่ถูกทำให้ซับซ้อนตั้งแต่ต้นมักไปไม่รอด เพราะฉะนั้นควรสร้างระบบที่ง่ายที่สุดก่อน แล้วค่อยเพิ่มความซับซ้อนตาม requirement

    • แล้วควรหยุดเมื่อไร? มีเหมือน "บอสสุดท้าย" หรือจุดวิกฤตของความซับซ้อนหรือเปล่า
  • ฉันเห็นด้วยกับเจตนาของบทความ แต่คิดว่าการมาถึงของ cloud infrastructure ทำให้คำจำกัดความของ "ความเรียบง่าย" เปลี่ยนไป ในอดีตมันเหมือนเป็นการเลือกระหว่าง "ง่ายแต่ไม่ scalable" กับ "ซับซ้อนแต่ scalable" แต่ตอนนี้ไม่ใช่แบบนั้นแล้ว โซลูชัน rate-limiting แบบ in-memory อาจง่ายบนเซิร์ฟเวอร์เครื่องเดียว แต่พอมีแค่สองเซิร์ฟเวอร์ก็กลายเป็นปัญหา distributed state ทันที ในทางกลับกัน managed service อย่าง DynamoDB หรือ ElastiCache กลับทำหน้าที่เป็นแหล่งความจริงหนึ่งเดียวได้ไม่ว่าจะมีโหนดเดียวหรือ 1000 โหนด และลดความซับซ้อนได้มาก ถ้ามองจากแนวคิดว่า "ระบบที่เรียบง่ายย่อมแข็งแรงกว่า" การใช้ managed service ก็อาจเรียบง่ายกว่าในระดับพื้นฐานด้วยซ้ำ เพราะช่วยลบปัญหาซ้ำ ๆ อย่างข้อมูลสูญหายหรือการจัดการ distributed state ไปได้ ดูเหมือนว่าทุกวันนี้นิยามของ "สิ่งที่ง่ายที่สุด" ได้เปลี่ยนมาเป็นการใช้ managed service อย่างชาญฉลาดแทนการดูแลเอง และปัจจุบันการเลี่ยง external dependency ไม่ได้ช่วยลดความซับซ้อนเสมอไป ตรงกันข้าม การ leverage ระบบที่แยกออกมาและผ่านการพิสูจน์แล้วอย่างมีประสิทธิภาพกลับช่วยประหยัดทั้งเวลาและค่าใช้จ่ายมากกว่า

    • ฉันว่าเรื่องนี้ไม่ได้จำกัดอยู่แค่ cloud แม้แต่บนเซิร์ฟเวอร์เดี่ยว ก็ถกกันแบบเดียวกันได้ระหว่าง flat file, sqlite, postgres และตัวเลือก storage อื่น ๆ ทุกวันนี้ความจริงคือมีซอฟต์แวร์มหาศาลที่เพิ่มความซับซ้อนเพียงเล็กน้อย แต่ให้ความสามารถมหาศาล แน่นอนว่าทุกทางเลือกมี trade-off ดังนั้นวิจารณญาณจึงยังจำเป็นเสมอ การเลือก managed service อย่าง Amazon ตั้งแต่แรกไม่ได้เป็นคำตอบตายตัวไปทุกกรณี อันที่จริงฉันก็เคยได้ยินหลายกรณีที่เสียใจภายหลังเพราะเลือก DynamoDB ทั้งที่ขนาดงานไม่เหมาะ
  • ฉันเห็นด้วยกับคำกล่าวที่ว่า "ทำให้มันง่ายที่สุดเท่าที่จะทำได้ แต่อย่าทำให้ง่ายไปกว่านั้น" ฉันพยายามยึดหลักนี้อยู่เสมอ แต่ก็สงสัยตลอดว่าตัวเองพลาดโอกาสลดความซับซ้อนที่ไม่จำเป็นเพราะไม่รู้เทคโนโลยีใหม่ ๆ หรือว่าทุกคนรอบตัวต่างหากที่กำลังตกหลุมความซับซ้อนโดยไม่จำเป็น มันยากจะรู้ว่าเครื่องมือใหม่ใช้ได้จริงหรือไม่ถ้าไม่เคยลองในโปรเจกต์จริง และในทางกลับกัน ฉันก็เคยเห็นว่าการยัดเครื่องมือใหม่เข้าโปรดักชันเพียงเพื่อการเรียนรู้ของตัวเองนั้นสร้างภาระให้ทีมมากแค่ไหน

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

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

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

    • เพราะเรื่องนี้เอง ฉันจึงพยายามระวังอย่างมากไม่ให้ตกไปสู่ "การพัฒนาเพื่อเรซูเม่"