จงนึกถึง Simplicity ก่อน Generality และ Use ก่อน Reuse

Kan Ouivirach
Nov 9, 2020

--

ในการพัฒนาซอฟต์แวร์​ ผมเชื่อว่าทุกคนมีความตั้งใจที่อยากจะเขียนโค้ดให้ดีๆ อยากจะเขียนโค้ดให้สวย อยากจะทำให้มันกลางๆ (general) ไม่ว่าใครก็ตามสามารถหยิบเอาฟังก์ชั่น หรือโค้ดของเราไปใช้งานได้ต่อได้ง่ายๆ (reusable) แต่ในโลกความเป็นจริง จากประสบกาณ์ของผมเอง การที่โค้ดของเราจะเป็นแบบนั้น “ตั้งแต่แรก” เกิดขึ้นได้ยาก หรือแทบจะเป็นไปไม่ได้เลย

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

ฟังก์ชั่นหนึ่งที่ใช้สร้าง Shortcode ใน WordPress

ดูดี? 🤣 ผมอนุญาตให้คนอ่านตัดสินเองครับ ฟังก์ชั่นนี้มีข้อดีขึ้นมันสามารถ reuse ได้ครับ ได้ทุก requirement ที่รับมาเลย ข้อเสีย? มันมีจุดประสงค์เยอะมากในตัวมันเอง มันแลกมากับ complexity ที่สูงขึ้น และ maintenance cost ที่ต้องเสียไปครับ แล้วก็เกิด tribal knowledge ขึ้น คือคนที่รู้เรื่องฟังก์ชั่นนี้จะเป็นแค่คนกลุ่มเล็กๆ คนที่เข้ามาใหม่จะไม่ค่อยกล้าแตะฟังก์ชั่นนี้เลย ถึงตรงนี้อาจจะมีบางคนบอกว่า อ้าวก็เขียนเทสคลุมไว้สิ มันเป็น executable document นะ.. ผมขอตอบว่าฟังก์ชั่นนี้มีเทสครับ มีเทสครบทุกกรณีด้วย แต่แค่เทสฟังก์ชั่นนี้ฟังก์ชั่นเดียวมีประมาณ 1k กว่าบรรทัดนะครับ 😂 maintain โค้ดก็ยากแล้ว นี่ maintain ตัวเทสยิ่งใช้ effort อัดเข้าไปอีก

พอดีผมซื้อหนังสือ 97 Things Every Software Architect Should Know ไว้นานล่ะ ลองมาเปิดๆ อ่านดู เจอบทหนึ่งที่จั่วหัวไว้ตรงกับปัญหาที่ผมเจอด้านบน คือ Simplicity Before Generality, Use Before Reuse (ผู้เขียนเค้าเขียนบทความไว้บน Medium ของเค้าไว้ด้วย ลองตามไปอ่านกันนะ)

เค้ากล่าวไว้ประมาณว่า..

ปัญหาที่เกิดขึ้นโดยปกติในเฟรมเวิร์คแบบ component คือหลายๆ อย่างถูกออกแบบให้เป็น general purpose โดยที่ไม่ได้อ้างอิงถึงตัว application และการใช้งานจริงๆ ลองนึกภาพพวก Software as a Service ทั้งหลายไว้ก็ได้ คือมันมักจะมีอะไรที่ไม่ตอบโจทย์ และเราจำเป็นต้อง customize ให้ตรงกับความต้องการของเราเองเสมอ

และในหลายๆ ครั้ง generalization จะกลายมาเป็นงานที่ดึงออกจาก direction และเพิ่ม complexity เข้าไปมากกว่าที่จะลด

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

เวลาที่เกิด 2 ทางเลือก ให้เราเลือกทางที่ simpler ไว้ก่อน ในทางปฏิบัติ เราจะสามารถปรับไปทาง general ได้ง่ายกว่า ถ้าใครมาสาย machine learning เค้าก็จะบอกว่า เฮ้ย ถ้าคุณมี 2 โมเดลที่ทำนายแม่นพอกัน ให้เลือกโมเดลที่ simpler นะ เพราะว่าโมเดลที่ simpler มันจะสามารถ generalize กับข้อมูลได้มากกว่านั่นเอง

ถึงแม้ว่า software architect หลายๆ คนจะให้คุณค่ากับ generality แต่เราก็ไม่ควรที่จะทิ้ง specificity เร็วเกินไปนะ ไม่งั้นสุดท้ายเราอาจจะตกอยู่ในโลกของ configuration ที่โคตรซับซ้อน และการมี interface หรือ parameter list ที่โคตรใหญ่แบบโค้ดของผมด้านบน (ผมเก็บไว้เตือนสติตัวเอง ว่าจะไม่ทำอีก)

สุดท้ายขอย้ำอีกครั้งครับ “จงนึกถึง Simplicity ก่อน Generality และ Use ก่อน Reuse” 😎

--

--

Kan Ouivirach

Data Craftsman. Passionate in software engineering, data engineering, and data science. ♥