9 หลักการในการเขียนโค้ดให้สะอาด อ่านง่าย ( Clean Code )

บ่อยครั้งหรือปล่าวที่เวลาเราดูโค้ดคนอื่นแล้วตำหนิเค้าหรือก็กล่าวออกไปว่า “อะไรกันนี่ นี่มันสปาเก็ตตี้โค้ดชัดๆ” หรือไม่ก็ “ทำไมคุณเขียนโค้ดได้แย่และอ่านไม่ออกขนาดนี้ ” หรือ “ทำไม่เขียนโค้ดยากจัง ง่ายๆก็มี” หรือ … อะไรอีกเยอะแยะมากมายที่คุณจะคิดไปว่าโค้ดของคุณนั้นเจ๋งแนวทางของคุณนั้นถูกต้องแล้ว !!! ช้าก่อน แล้วคุณแน่ใจแล้วจริงๆหรอว่าโค้ดคุณนั้นเทพ ถ้าคุณลองให้คนอื่นเค้า review code คุณล่ะคุณแน่ใจแล้วหรือว่าคุณจะไม่โดนตำหนิแบบเดียวกันนี้เลย

พูดง่ายคือคือคุณเข้าใจถูกหรือยังว่าการเขียนโค้ดที่ดีจริงๆแล้วมันคืออะไร แล้วรู้จริงๆหรือเปล่าว่า Clean code ในความหมายจริงๆนั้นคืออะไรก่อนที่จะ Express ออกไปให้กระทบกระเทือนต่อความเชื่อมั่นของโปรแกรมเมอร์หรือเพื่อนร่วมงาน

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

I  Bad code does too much – Clean code is focused

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

A functional unit on a given level of abstraction should only be responsible for a single aspect of a system’s requirements. An aspect of requirements is a trait or property of requirements, which can change independently of other aspects.

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

II ภาษาที่ใช้ต้องถูกสร้างมาเพื่อแก้ปัญหานั้นโดยเฉพาะ

It is not the language that makes a program look simple, but the programmer who makes the language appear simple.

Robert C. Martin กล่าว

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

III โค้ดที่ดีต้องไม่ซ้ำซ้อน ( Redundant )

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

 IV กลับไปอ่านโค้ดตัวเองแล้วมีความสุข

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

ฝรั่งมักมีหลักต่างๆให้เราจำง่ายๆ เสมอ ยกตัวอย่างเรื่องที่เราว่ามานี้ฝรั่งก็เรียกมันว่า หลักการ KISS  ( Keep It Simple, Stupid!) และหลักการ  YAGNI (You Ain’t Gonna Need It) หลักการ KISS กล่าวว่าไม่ว่าระบบใดๆก็ตามจะทำงานดีที่สุดถ้าเราทำให้มันง่ายดีกว่าทำให้มันซับซ้อนไม่จำเป็น เพราะฉนั้น Simplicity ก็คือกุญแจหลักสำหรับการออกแบบซอฟท์แวร์ที่ดี ส่วน YAGNI นั้นเป็นแบบปฏิบัติที่ช่วยให้เราโฟกัสกับสิ่งที่ง่ายที่สุดที่ทำให้ซอฟท์แวร์เราทำงานได้เท่านั้น

V ) นักพัฒนาโปรแกรมคนอื่นสามารถพัฒนาต่อจากเราได้ไม่ยาก

เราไม่ได้เขียนโค้ดให้เราอ่านแค่เพียงคนเดียว (ถ้าจะเถียงก็ อย่างน้อยก็ compiler). ทุกวันนี้เราทำงานเป็นทีม โค้ดที่เราเขียนออกไปต้องให้นักพัฒนาคนอื่นเข้าใจได้ด้วย ไม่เห็นแก่ตัว ให้คิดถึงคนอื่นอยู่ตลอด อย่าทรมาน developer คนอื่นด้วยการเขียนโค้ดที่อ่านเข้าใจยาก ดูแลยาก หรือเขียนต่อยากอีกต่างหาก ทำใหม่ดูเหมือนจะง่ายกว่า พึงตระหนักข้อนี้ไว้เพราะสักวันหนึ่งเราก็จะเป็นคนที่อ่านโค้ดของคนอื่นเหมือนกัน

VI ) โค้ดต้องมี dependencies น้อยที่สุด

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

VII ) หน่วยเล็กๆดีกว่า (Smaller is Better)

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

VIII ) โค้ดที่ดีต้องมี Unit tests และ Acceptance tests

เราจะรู้ได้ยังไงว่าโค้ดเราเขียนถูกต้องตาม requirement หรือเปล่าหากเราไม่มีการเขียน unit tests หรือเราจะแน่ใจได้ยังไงว่าหากเรามีการเปลี่ยนแปลงโค้ดหรือเพิ่มเติมโค้ดเข้าไปใหม่โค้ดเก่าที่เราที่เราไม่ได้แก้ไขอะไรจะไม่ได้รับผลกระทบและทำงานถูกต้อง โค้ดที่ไม่มีการเขียน test เป็นโค้ดที่ไม่สะอาด ง่ายๆคือเราควรจะเรียนรู้หลักการเขียน unit test เพื่อทำให้โค้ดที่เราเขียนสะอาดและมีคุณภาพด้วย

IX ) โค้ดที่ดีต้องสื่อความหมายในตัว ( Expressive )

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

 

เรียบเรียงมาจากบทความ

TOP 9 Principles Clean code

Aside