วิธีการเขียน Clean Code แบบ Uncle Bob
การเขียน Code ให้สะอาดนั้นเป็นอะไรที่ยาก ผมเขียนโค้ดมามากกว่า 10 ปี แต่ก็ยังรู้สึกว่าตัวเองเขียน Code ไม่สะอาดเท่าที่ควร ยิ่งเขียน ยิ่งเห็นสิ่งที่แก้ได้ และถ้าต้องกลับไปอ่านโค้ดเก่าๆที่เคยเขียนเมื่อก่อน ผมยอมเขียนใหม่หมดเลยน่าจะดีกว่า
แต่ความคิดแบบนี้มันไม่ยั่งยืน โดยเฉพาะเมื่อคุณจะต้องทำ Software ที่มีคนใช้งานจริงๆในระยะยาว การที่คุณจะต้องมานั่งเขียนใหม่เรื่อยๆนั่นเป็นไปไม่ได้แน่ๆ และเมื่อคุณต้องทำการทำงานในทีม ถ้าคนอื่นอ่านโค้ดของคุณไม่รู้เรื่อง และไม่สามารถพัฒนาต่อได้ โค้ดของคุณก็เป็นแค่ขยะ
ตอนนี้ทีมที่บริษัทของผมเรื่มใหญ่ ผมเริ่มเห็น Style การเขียนโค้ดที่แตกต่าง หลายคนสามารถทำโค้ดที่ไม่ซับซ้อนให้มันซับซ้อนได้เพราะวิธีการเขียน ผมเลยสนใจวิธีการเขียนโค้ดให้สะอาด
และก็ได้ไปเจอ Video ของ Uncle Bob หรือ Robert C. Martin ขณะการทำ Knowledge Sharing ของบริษัท Uncle Bob คือหนึ่งในผู้เขียน Agile Manifesto หรือสิ่งที่เราใช้ Define ว่าอะไรคือ Agile บล็อกนี้ผมจะมาเขียนสิ่งที่ผมได้เรียนรู้จากการดู Video ของ Uncle Bob
WTFs / minute
หากคุณอยากรู้ว่าโค้ดของคุณดีหรือแย่ให้นับจำนวน WTF ตอนทำ Code Review หรือตอนที่คนอื่นอ่านโค้ดของคุณ ถ้าจำนวน WTF น้อย แปลว่าโค้ดของคุณน่าจะค่อนข้างดี ถ้าเยอะก็คงจะอ่านยากแล้ว เพราะฉะนั้นเกณฑ์ในการดูว่าโค้ดของคุณดีรึยัง ให้นับจำนวน WTFs per minute 😂
ตั้งชื่อให้เหมาะสม
ชื่อเป็นสิ่งที่สำคัญสุดๆ เราต้องตั้งชื่อ Variable, Function, Argument, Class และอื่นๆอีกมากมาย แน่นอนว่าบางทีคุณก็คิดไม่ออกว่าจะตั้งชื่ออะไร ผมก็เป็น
ชื่อทุกชื่อ ควรจะบอกว่ามันมีทำไม มีเพื่ออะไร ผมเคยหลาย Project ของคนไทยตั้ง Variable ใน Class Quotation ว่า f1, f2, f3 ไล่ๆไปเรื่อยถึง f10
การตั้งชื่อ f1 - f10 ไม่ได้บอกอะไรเกี่ยวกับ Variable ตัวนั้นเลย จะดีกว่าไหมถ้าคุณตั้งชื่อเช่น
var customerName
var customerAddress
var customerPhoneNumber
เพราะฉะนั้นจงตั้งชื่อให้สื่อถึงสิ่งที่คุณต้องการให้มันทำ อย่ากลัวว่าชื่อมันจะยาว ตั้งชื่อที่มันเข้าใจง่ายดีกว่า แล้วใช้ IDE ดีๆให้มัน AutoComplete ให้คุณ
Functions
- Function ควรจะสั้น บรรทัดใน Function ควรจะไม่เกิน 170 บรรทัด หาเกินกว่านั้นคุณควรจะแยก Function ให้เป็น โunction ย่อยๆ และตั้งชื่อ function เหล่านั้นให้เข้าใจว่ามันจะทำอะไร
- Block ใน if else, while statement ควรมีแค่หนึ่งบรรทัด หนึ่งบรรทัดนั้นอาจจะเป็น Function call ไปที่ชื่อ Function ที่เข้าใจง่าย
- ควรทำแค่อย่างเดียว ถ้า Function คุณทำหลายอย่าง ให้แยกออกเป็น Function ย่อยๆซะ จนกว่า Function นั่นจะทำแค่อย่างเดียว
- Step-Down Rule เขียน Function ให้สามารถอ่านจากบนลงล่างได้ โดยเรียง Function ย่อยไว้ด้านบนและตามด้วย Function ที่เรียกใช้ Function ก่อนหน้านั้น
- DRY - Don’t Repeat Yourself เป็นสิ่งที่ทุกโปรแกรมเมอร์ควรจะรู้ ถ้า Function ทำสื่งที่คล้ายๆกันหรือเหมือนกัน ห้ามก็อปไปวางอีกครั้งเด็กขาด ให้เขียนเป็น Function แทน
Comments
ผมเคยคิดว่าการ Comment เป็นสิ่งที่ดี แล้วเราควรจะเขียน Comment เกือบทุกบรรทัดในการเขียนโค้ด แต่หลังจากลองเขียน Comment จริงๆก็รู้ว่ามันเป็นอะไรที่ซ้ำซาก เช่นการเขียน Comment ให้ Variable ชื่อ customerName การที่เขียน comment เช่น // The name of the customer มันไม่จำเป็น เพราะชื่อ variable ก็บอกอยู่แล้ว
Uncle Bob จึงบอกว่าการเขียน Comment เป็นสื่งที่แสดงว่าเราเขียนโค้ดไม่ดี ถ้าเราเขียนโค้ดดี โค้ดควรจะอ่านรู้เรื่องอยู่แล้ว ไม่ว่าจะเป็นเพราะการตั้งชื่อที่ดี การเขียนในสไตล์ที่อ่านไม่ยาก คุณไม่จำเป็นต้องมี Comment เลย เพราะคนที่จะอ่านโค้ดของคุณ ก็ต้องเขียนโปรแกรมเป็นอยู่แล้ว ถ้าเขียนโค้ดดี ก็ไม่จำเป็นต้องมี Comment
แต่ในบาง case คุณก็ต้องมี comment อยู่ดีเช่น comment license หรือโค้ด ที่เข้าใจได้ยากไม่ว่าจะคุณจะ clean ยังไงก็ตามแล้ว เพราะฉะนั้น ให้ comment เป็นสิ่งสุดท้ายที่คุณทำ ถ้าคุณไม่สามารถทำความสะอาดโค้ดของคุณได้แล้ว
Test
การเขียน Test นี่เป็นเรื่องที่ผมไม่ชอบเลยเมื่อก่อน เพราะว่ามันเหมือนเราต้องเขียนโค้ดสองรอบ ทั้งๆที่เรารู้แล้วว่าโค้ดมันเวิร์คอยู่แล้ว แต่นั้นและคือสาเหตุที่เราเขียน Test เพราะว่าเราต้องการ เช็คมันสองรอบ เหมือนว่าทำไมบัญชีต้องจดทั้งรายรับ และรายจ่าย เพื่อที่จะได้รู้ว่าถ้ามันไม่ตรงกัน มันก็ต้องมีอะไรสักอย่างผิดพลาด คุณคงไม่เจอนักบัญชีที่จดแค่รายรับ แต่ไม่จดรายจ่าย
การเขียน Test ในโปรแกรมก็เหมือนกัน เพราะว่าถ้าเราหยุดเขียน Test เมื่อไหร่ เราไม่มีทางมั่นใจได้เลยว่า โค้ดของเราจะทำงานได้ถูกต้องหรือใหม่
แล้วเราต้อง Test อะไรบ้างละ? คำตอบคือ ทุกอย่าง เพราะถ้าสมมุติคุณเขียน Test แค่ 80% แปลว่าคุณกำลังบอกทุกคนว่าอีก 20% ของแอพนั้นมีโอกาสที่จะพัง
Test จะช่วยเยอะมาก หากคุณทำงานใน Team ที่คนอื่นมีโอกาสจะมาแก้ไขโค้ดของคุณ หรือถ้าคุณโค้ดคนเดียว หากคนกลับมาโค้ดโปรเจ็คที่คุณไม่ได้แตะมาแล้วสักหนึ่งปี การมี Test จะช่วยให้คุณมั่นใจว่าสิ่งที่คุณจะแก้จะไม่ทำให้ระบบคุณพัง อีกหนึ่งประโยชน์ของ Test คือ มันคือตัวอย่างการใช้งานระบบของคุณ เพราะถ้าคุณทำ Test ได้ 100% Test นั้นจะเป็นสิ่งที่บอกวิธีการใช้งานทุก Class ทุก Function ในระบบของคุณ โปรแกรมเมอร์แทบทุกคนคงเห็นด้วยว่าการอ่านโค้ดนั้น สะดวกสบายกว่าการไปอ่าน Document ยาวๆ
การที่จะเขียน Test ให้สำเร็จได้สิ่งที่คุณต้องมีก็คือวินัย ถ้าคุณขาดวินัยในการเขียน Test หรือเรื่ม Comment Test ออกเมื่อไหร่ คุณจะเลิกเขียน Test แน่นอน เพราะฉะนั้นจงเรื่มเขียน Test ให้เร็วและมีวินัย หรือถ้าทำ Test-Driven ได้ยิ่งดี
ความสำคัญของ Software
หลายคนๆ แม้กระทั่ง Programmer เองคงไม่ได้ให้ความสำคัญกับโปรแกรมที่ตัวเองเขียนมากเท่าที่ควร หากคุณลองคิดดีๆ ของแทบทุกอย่างควบคุมด้วย Software เช่นรถที่คุณขับ หรือเครื่องบินที่คุณนั่ง ล้วนแต่มีแอพพลิเคชั่นเล็กๆนับพันเพื่อที่มันจะทำงานได้ถูกต้อง หากคุณเขียน Software ที่ไม่ดีและมีบัค แปลว่าคุณมีสิทธิที่จะทำให้คนอื่นเสียชีวิตได้เลยนะ
สุดท้าย เขียนโค้ดเหมือนว่าคนที่จะมารับช่วงดูแลโค้ดของคุณต่อเป็นคนโรคจิตหัวรุนแรงที่รู้ว่าบ้านคุณอยู่ไหน
หากคุณเป็นสายดูวิดีโอผมแนะนำให้ไปดู Playlist นี้ของ Uncle Bob หรือถ้าคุณเป็นสายหนังสือลองอ่านเล่มนี้ดูนะครับ Clean Code : A Handbook of Agile Software Craftsmanship (Robert C. Martin)