👶Code Smells
โค้ดคุณส่งกลิ่นเน่าออกมาหรือเปล่า ?
เวลาที่เราทำงานกับโค้ดอยู่เคยรู้สึกแปลกๆกับโค้ดกันไหม เช่น ทำไมต้องเขียนแบบนี้ ทำไมใช้ยากจัง มันควรเป็นแบบนี้จริงๆเหรอ อะไรทำนองนี้ นั่นแหละคือสัญญาณแบบนึงที่บอกว่าโค้ดพวกนั้นกำลังมีปัญหา ซึ่งเขาเรียกว่ามันกำลังส่งกลิ่นเหม็นออกมา ดังนั้นหน้าที่ของ developer ที่ดีคือไล่ตามกลิ่นพวกนั้นไปแล้วจัดการอย่าให้โค้ดเน่าซะ ( ไม่ต้องเอาจมูกไปชิดจอแล้วไล่ดมโค้ดชาวบ้านไปทั่วนะครับ 🤣 )
Code smells คือหลักการที่เอาไว้ตรวจว่า โค้ดที่เราออกแบบไว้มันไปผิดหลักการออกแบบหรือเปล่า ซึ่งถ้าผิดมันหมายความว่าโครงสร้างพวกนั้นจะมีปัญหาในอนาคต และมีอีกชื่อนึงคือ Design Smells
❓ โค้ดส่งกลิ่นเน่าแล้วไง ?
คุณอยากทำงานกับโปรเจคแบบนี้ไหม แก้โค้ด 1 จุด bug ผุดกระจาย หรือ เพิ่ม 1 feature แต่ต้องไปแก้ 10 feature ที่ไม่เกี่ยวข้องด้วยไม่งั้นเพิ่ม feature ใหม่ไม่ได้ และอื่นๆอีกมากมาย ซึ่งถ้าไม่โรคจิตพอก็น่าจะตอบว่า "ไม่" แล้วถามต่อว่า แล้วจะมีใครอยากมาทำงานโปรเจคแบบนี้ไหม? คนที่อยู่ในโปรเจคแบบนี้เขาอยากรีบหนีไปทำโปรเจคอื่นไหม? นี่ยังไม่นับรวมเรื่อง deadline ของโปรเจคนี้ที่กำลังบีบเข้ามาด้วยนะ ... แค่นี้ก็น่าจะเห็นภาพแล้วใช่ไหมว่า โค้ดเน่ามันส่งผลเสียยังไง . . . หรือก็เป็นอยู่จนชินกันแล้ว ? 😱
🤢 อาการของกลิ่นเน่า
👃 Rigidity (ดื้อ)
คืออาการของโค้ดที่แก้ไขเพิ่มเติมยาก แม้ว่าจะเป็นแค่เรื่องง่ายๆก็ตาม เช่น แก้ 1 จุด แต่มันไปกระทบกับโค้ดอื่นๆที่เกี่ยวข้องกับมัน ทำให้เราต้องไปตามแก้เพื่อให้มันทำกับแบบใหม่ได้ แย่กว่านั้นอีกแก้ A กระทบ B, แก้ B กระทบ C, แก้ C ดันย้อนมากระทบ A เป็นงูกินหาง
แก้ 1 กระทบ 10 เคยไหมคิดว่าจะแก้โค้ดแค่ 1-2 วันวัน แต่พอทำไปทำมาบางทีกินเวลาเป็น 1-2 อาทิตย์เลย ทำให้เราไม่สามรถประเมินว่างานจะเสร็จเมื่อไหร่ได้เลย 😧
👃 Fragility (เปราะบาง)
คืออาการของโค้ดที่ แก้ 1 จุด bug ผุดเป็นดอกเห็ด เลวร้ายกว่านั้นอีก bug ที่ผุดขึ้นมาในบางทีไม่เกี่ยวข้องกับเรื่องนั้นเลย เช่น แก้โปรแกรมลงเวลา แล้ว bug ไปเกิดตอนคำนวณเงินเดือน ยิ่งแก้ก็ยิ่งผลิด bug ออกมาไม่จบไม่สิ้น
แก้ 1 จุด bug ผุดเป็นดอกเห็ด เคยไหม bug มันเยอะแก้ยังไงก็ไม่หมด จนคิดว่าเขียนส่วนนั้นใหม่ตั้งแต่ต้นอาจจะเร็วกว่า ปัญหานี้ developer ทุกคนรู้จักดี และบางครั้งรู้ด้วยว่ามันเป็นไฟล์นี้ แต่ไม่มีคนอยากไปแก้มันเพราะกลัวฟาร์มเห็ดจะผลิบาน
👃 Immobility (ย้ายที่ไม่ได้)
คืออาการของโค้ดที่เรารู้สึกว่ามันไม่ควรอยู่ตรงนี้นะ แต่ก็ย้ายมันออกจากตรงนี้ไม่ได้เพราะมันถูกใช้งานอยู่ และถ้าจะย้ายมันไปที่ๆของมันก็อาจจะเสียเวลามากจนไม่คุ้ม (พบเจอได้บ่อยกับพวก helper class กับ database connector หรือไม่ก็โค้ดที่คนอื่นเขียนไว้ไม่อยากไปยุ่งกับมัน)
👃 Viscosity (หนืด)
เคยไหมเวลาที่จะเขียนโค้ดบางที เรารู้ว่ามันควรจะทำยังไงถึงจะถูก แต่ถ้าทำแบบนั้นมันจะเสียเวลา เราเลยทำแบบให้มันใช้งานได้ไปก่อน
ทำให้ใช้งานได้ไปก่อนเดี๋ยวค่อยกลับมาแก้ การทำแบบนั้นทำให้โค้ดที่จะตามมาในอนาคต มีโอกาสสุ่มเสี่ยงที่จะทำให้โค้ดออกนอกลู่นอกทางจากสิ่งที่มันควรจะเป็น แล้วเมื่อไหร่เราจะไปแก้โค้ดพวกนั้นกันนะ ? 😧
👃 Needless Complexity (ซับซ้อนโดยไม่จำเป็น)
คืออาการของโค้ดที่เวลาใช้งานมันซับซ้อนโดยไม่จำเป็น เช่น ไปเรียกใช้คลาสไม่เหมาะสมแต่มันก็ทำงานได้ถูกอยู่นะ หรือโค้ดที่ถูกออกแบบซับซ้อนโดยไม่จำเป็น เช่นจะใช้คลาสนี้ต้องไปสร้างหรือเรียก method นั่นนู่นนี่เสียก่อนถึงจะทำงานได้
ซับซ้อนโดยไม่จำเป็น ตัวอย่างที่เจอได้ง่ายสุดๆคือ จะแสดงเลขทศนิยมสูงสุดเพียงแค่ 2 ตำแหน่ง เช่น 3.1415 จะต้องแสดงเป็น 3.14 แต่ developer ไปเขียนสูตรคำนวณเพื่อตัด string หรือไม่ก็ x 100 เข้า แล้วหาร 100 ออกบลาๆ ซึ่งทำไมไม่ใช่ Math.Round() แฟร๊ พูดแล้วขึ้น 😡
👃 Needless Repetition (ใช้โค้ดซ้ำโดยไม่จำเป็น)
เวลาที่เราเจอโค้ดบางส่วนที่คล้ายๆกัน ส่วนใหญ่เราก็จะ copy ไปวางอีกที่ แล้วก็ค่อยทำการแก้ให้เหมาะกับจุดนั้นๆใช่ไหม แต่ในบางทีการ copy โค้ดไปมันอาจจะมีบางอย่างที่ไม่เกี่ยวกับเรื่องนั้นๆเลยติดไปด้วยก็ได้ ซึ่งถ้าเราลืมเอาออกมันก็จะติดกับงานส่วนนั้นเรื่อยๆ แล้วถ้าคนอื่นมาเจอโค้ดนั้นแล้ว copy ไปใช้บ้างล่ะ? แน่นอนมันก็จะมีขยะนั้นตามไปด้วยลามไปหลายๆที่เช่นกัน เพราะส่วนใหญ่เราจะไม่สนใจโค้ดคนอื่นหรอกแค่ใช้งานได้ก็พอแล้วนิ
โค้ดไร้ประโยชน์กระจายตัวไปทั่ว สมมุติว่ามีการเปลี่ยนการทำงานเรื่องที่เกี่ยวกับเจ้าโค้ดไร้ประโยชน์นั้นเข้าล่ะ แน่นอนมันก็ยังไร้ประโยชน์เช่นเดิมแต่สิ่งที่เพิ่มขึ้นมาคือ ทุกจุดที่มันอยู่ bug ก็จะผุดขึ้นมาด้วย โดยที่เรื่องนั้นๆไม่เกี่ยวกับเจ้าโค้ดไร้ประโยชน์นี้เลยก็ตาม
ตัวอย่าง แก้โครงสร้าง database รถยนต์ แต่เรื่องคำนวณวันหยุดพัง เรื่องตารางนัดหมายพัง เรื่องระบบประชุมพัง เพราะแต่ละจุดดันมีโค้ดไร้ประโยชน์ที่มันต้องไปดึงข้อมูลรถยนต์ซ่อนอยู่ในนั้นด้วย แล้วมันไม่ได้ถูกแก้ตามโครงสร้าง database ตัวใหม่ ก็เลยพัง ทำให้เราเสียเวลาไปหาสาเหตุที่ไร้สาระแต่เป็นงานด่วน 😱
👃 Opacity (เข้าใจยาก)
คือรูปแบบของโค้ดที่เข้าใจได้ยากอ่านแล้วคลุมเครือว่ามันใช้ทำอะไรกันแน่ เหตุการณ์นี้จะเจอบ่อยเมื่อเพิ่มความสามารถให้กับโค้ดเข้าไปเรื่อยๆ ตอนแรกๆก็ไม่ได้ซับซ้อนอะไร แต่หลังๆมาเหมือนโค้ดตัวนี้จะทำงานได้ครอบจักรวาลเลย สรุปเอ็งมีหน้าที่ทำอะไรกันแน่ แล้ว feature ใหม่นี่จะต้องเอาไปยัดไว้กับเอ็งหรือเปล่า?
🤔 ทำไมโค้ดถึงเน่า ?
หลักๆก็คือออกแบบไม่ดีนั่นแหละ ส่วนสาเหตุการออกแบบไม่ดีส่วนใหญ่เกิดจาก การขาดประสบการณ์ของคนเขียนโค้ด หรือ คนเขียนโค้ดไม่ได้เข้าใจหัวใจของการออกแบบ เลยทำให้ไม่สามารถรับมือกับ Requirement หรือเวลาเกิด Requirement Change ได้ดีพอ
พูดสั้นๆ กลับไปเก็บ exp มาให้เยอะๆซะ (รวมถึงผมด้วย) เพราะการเขียนซอฟต์แวร์ต้องเรียนรู้ตลอดไปไม่สามารถหยุดเรียนได้ เทคโนโลยีในตอนนี้เปลี่ยนวันต่อวันเลยทีเดียว 🤧
🎯 บทสรุป
โค้ดเน่าทำให้การพัฒนาซอฟต์แวร์กลายเป็นนรก เพราะ โปรเจคประเมินเวลาและค่าใช้จ่ายไม่ได้ ไม่มีคนอยากทำโปรเจคนั้น ดังนั้นจงอย่าทำให้มันเน่า
แล้วจะทำยังไงมันถึงจะไม่เน่า ? ... ออกไปเก็บประสบการณ์ซะ อ่านโค้ดจาก GitHub คนที่เก่งๆ ร่วม Contribute source code กับ GitHub ระดับโลกซักตัว เราจะได้รับคำแนะนำมาเต็มเลย และที่สำคัญที่สุดคือไปศึกษาหลักการออกแบบที่ดีมาซะ
👨🚀 คอร์สที่จะช่วยให้โค้ดไม่เน่า
👦SOLID Design Principles👦Test-Driven Development🤴Design PatternsLast updated