หลักการพื้นฐานในการเขียนโค้ดที่ดีในทุกภาษา

Computer Science Jul 20, 2020

แต่ละภาษาที่ใช้ในการเขียนโปรแกรมมักจะมี Best Practice หรือ Syntax ต่าง ๆ ที่เข้ามาช่วยเพื่อให้เราสวามารถเขียนโค้ดที่ดีขึ้น แน่นอนว่าการเขียนโค้ดให้ระบบของเราทำงานได้นั้นไม่ใช่เรื่องยากอะไร หากแต่การเขียนโค้ดที่ดีนั้น มีองค์ประกอบต่าง ๆ มากมาย โค้ดที่ดีไม่เพียงแค่ทำให้ระบบสามารถทำงานได้ตามวัตถุประสงค์ที่ตั้งไว้เท่านั้น หากแต่โค้ดที่ดียังทำให้นักพัฒนาทำงานกับระบบได้ง่ายขึ้นอีกด้วย ซึ่งโค้ดที่ดีนั้นไม่ได้มีเพียงแค่การตั้งชื่อให้สื่อความหมายเท่านั้น หากแต่ยังประกอบไปด้วยสิ่งอื่น ๆ อีกมากมาย รวมไปถึง Convention และข้อตกลงของแต่ละทีมด้วย ในบทความนี้ก็จะพาไปดูหลักการพื้นฐานต่าง ๆ ที่จะช่วยเราสามารถเขียนโค้ดได้ดียิ่งขึ้น ไม่ว่าจะเขียนภาษาใดก็ตาม


Naming

เรื่องแรกและเรื่องที่สำคัญที่สุด ย่อมหนีไม่พ้นเรื่องของการตั้งชื่อ การตั้งชื่อเป็นหนึ่งในสิ่งที่นักพัฒนาจะต้องเจออยู่ตลอดเวลาในการพัฒนาระบบ ไม่ว่าจะตั้งชื่อตัวแปร,​ ตั้งชื่อคลาส,​ ตั้งชื่อโฟลเดอร์,​ ตั้งชื่อไฟล์ ฯลฯ โดยส่วนตัวเชื่อในการตั้งชื่อว่าควรยึดถือหลัก 2C คือ Convention และ Convey meaning

Convention คือ การที่เราตั้งชื่อตามหลักการที่แนะนำของภาษานั้น ๆ เช่น Python อาจจะต้องตั้งเป็นแบบ Snake case หรือ Java อาจจะต้องเป็น Camel case แต่อย่างไรก็ตามหากมองในอีกมุมหนึ่ง Convention ก็อาจหมายถึงข้อตกลงภายในทีมได้เช่นกัน โดยส่วนตัวมองว่าควรยึด Convention ของทีมเป็นหลัก แต่หากเป็นไปได้ก็ควรสอดคล้องกับ Community เช่นกัน เพราะการพัฒนา Software ในปัจจุบัน เราพึ่งพา Third-party library ต่าง ๆ มากมาย

Convey meaning ก็ถือว่าตรงไปตรงมา คือ การตั้งชื่อให้สื่อความหมาย ปัจจุบันเวลาเราพัฒนาโปรแกรมเราใช้งาน Code editor หรือ IDE กันเป็นปกติอยู่แล้ว ดังนั้นการตั้งชื่อยาวก็ไม่ได้เป็นอุปสรรคที่เราต้องพิมพ์ให้ครบ เพราะโปรแกรมที่เราใช้จะช่วยเราในส่วนนี้อยู่แล้ว แต่อย่างไรก็ตาม Convey meaning ก็ควรจะต้องมอง Convention ร่วมด้วย เช่น การตั้งชื่อ Function ที่ปกติเรามักขึ้นต้นด้วย Verb แต่ในภาษาอังกฤษคำที่มีความหมายใกล้เคียงกันก็ค่อนข้างเยอะ จึงควรตกลงกันให้ดีว่าจะใช้คำอะไร เพื่อให้เป็นไปในทิศทางเดียวกัน และป้องกันความสับสนที่อาจจะเกิดขึ้น เช่น fetch, get, view, observe, download


DRY

Don't Repeat Yourself - เป็นหลักการที่บอกว่า เมื่อไรก็ตามที่เราก็อปโค้ดแปะ หรือก็อปแปะแล้วแก้นิดหน่อย เราควรแยกโค้ดส่วนนั้นออกมาเป็นฟังก์ชัน อย่างไรก็ตามมันเป็นหลักการที่แนะนำเท่านั้น ในบางกรณีก็ไม่จำเป็นต้องทำ ควรพิจารณาเป็นครั้ง ๆ ไป แต่ก็เป็นหลักการหนึ่งที่ดี ที่จะช่วยให้เราฝึกนิสัยในการเขียนโค้ดที่ง่ายต่อการปรับเปลี่ยน เพิ่มเติมในอนาคต


SRP

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


YAGNI

You Ain't Gonna Need It - คุณอาจไม่ต้องการมันหรอก เป็นหลักการที่ว่าเราไม่ควรเขียนโค้ด "เผื่อ" เอาไว้ เพราะคิดว่าอาจจะต้องใช้มันในอนาคต การเขียนโค้ดเผื่อนั้นมีข้อเสียในแง่ที่เป็นการเพิ่มปริมาณงานที่ไม่ก่อให้เกิดประโยชน์กับเป้าหมายในปัจจุบัน ยิ่งไปกว่านั้นยังทำให้โค้ดอ่านยากขึ้นอีกด้วย เพราะมีส่วนที่ไม่เกี่ยวข้องกับปัจจุบันมากเกินไป เช่น เราเขียนฟังก์ชันเพื่อแปลงข้อมูลที่ได้รับมาจาก XML ให้เป็น Object แต่เราคิดเผื่อไปด้วยว่าในอนาคตเราอาจจะอยากเปลี่ยนไปใช้ JSON ดังนั้นเราจึงเขียนโลจิกเผื่อเอาไว้ ซึ่งเป็นการเพิ่มความซับซ้อนให้ฟังก์ชันนั้น และยังไม่เกิดคุณค่ากับเป้าหมายปัจจุบันอีกด้วย รวมไปถึงในอนาคตอาจจะไม่ได้ใช้ด้วยซ้ำหากเกิดการเปลี่ยนแปลงเป็น CSV แทนที่ XML ไม่ใช่ JSON

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


KISS

Keep It Stupid Simple - ทำอะไรทำให้ง่ายเข้าไว้ เวลาเราเขียนโค้ดเพื่อแก้ปัญหาบางอย่างมันมักจะไม่ได้มีเพียงแค่วิธีเดียวเท่านั้นในการแก้ปัญหา ซึ่งแต่ละวิธีมักมีข้อดีข้อเสียแตกต่างกันไป หนึ่งในสิ่งที่สำคัญ คือ เราควรเลือกวิธีที่ง่ายที่สุดไว้ก่อน (แน่นอนว่าต้องเหมาะสมกับบริบทนั้น ๆ ด้วย) หลายครั้งที่เรามัก Overengineered บางอย่างไป ทั้ง ๆ ที่วิธีที่ง่ายกว่าก็สามมารถได้ผลลัพธ์เดียวกัน และยังง่ายต่อการต่อเติมในอนาคตอีกด้วย เพราะฟังก์ชันที่มีความซับซ้อนสูงนั้นมักจะมีการต่อเติมแก้ไขได้ยากกว่านั่นเอง นอกจานี้การเขียนโค้ดตามหลักการ KISS ยังทำให้เราใช้เวลา ซึ่งก็หมายถึง Cost ที่น้อยลงอีกด้วยนั่นเอง


📚 Hope you enjoy reading! 📚


Tags

Pittawat Taveekitworachai

A CS student who passionate about web and mobile technology with the belief that technology can enhance people's life.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.