| Topic 8 | The Essence of Good Design |
|---|
โลกนี้เต็มไปด้วยกูรูและผู้เชี่ยวชาญ ที่พร้อมจะแบ่งปันภูมิปัญญาที่สะสมมาเกี่ยวกับ 'How to Design Software' มีทั้ง acronyms, lists (ที่ดูเหมือนจะชอบมี 5 ข้อ), patterns, diagrams, วิดีโอ, งานทอล์ก และ (ในเมื่อมันคือโลกอินเทอร์เน็ต) ก็คงจะมีซีรีส์เจ๋ง ๆ เกี่ยวกับ Law of Demeter ที่อธิบายด้วยการร่ายรำประกอบเลยมั้ง
และพวกเรา—ผู้เขียนที่แสนใจดีของคุณ—ก็มีความผิดในเรื่องนี้ด้วยเหมือนกัน แต่เราอยากจะขอไถ่โทษด้วยการอธิบายบางอย่างที่เราเพิ่งจะเริ่มเข้าใจมันอย่างถ่องแท้เมื่อไม่นานมานี้เอง เริ่มจากคำกล่าวทั่ว ๆ ไปก่อนว่า:
| Tip 14 | Good Design นั้น Easier to Change กว่า Bad Design |
|---|
สิ่งที่เรียกว่า well designed คือมันต้องปรับตัวให้เข้ากับคนที่ใช้งานมันได้ สำหรับโค้ด นั่นหมายความว่ามันต้องปรับตัวด้วยการเปลี่ยนแปลงได้ ดังนั้นเราจึงเชื่อในหลักการ ETC (Easier to Change) หรือ ‘ทำให้เปลี่ยนง่าย’ นั่นเอง ETC. แค่นี้แหละ
เท่าที่เราบอกได้ design principle ทุกตัวที่มีอยู่นั้นล้วนเป็นกรณีพิเศษของ ETC ทั้งนั้น
ทำไม decoupling ถึงดี? ก็เพราะการแยกความรับผิดชอบ (isolating concerns) นั้นทำให้แต่ละส่วนเปลี่ยนแปลงได้ง่ายขึ้นไงล่ะ ETC.
ทำไม single responsibility principle ถึงมีประโยชน์? ก็เพราะเวลา requirements เปลี่ยน มันก็จะไปกระทบแค่โมดูลเดียว (single module) เท่านั้นเองไงล่ะ ETC.
ทำไมการตั้งชื่อ (naming) ถึงสำคัญ? เพราะชื่อที่ดีทำให้โค้ดอ่านง่าย และคุณก็ต้องอ่านมันให้รู้เรื่องก่อนที่จะแก้ (change) มันยังไงล่ะ ETC!
ETC คือ Value ไม่ใช่ Rule
Values คือสิ่งที่ช่วยให้คุณตัดสินใจได้ว่าจะทำอันนี้หรืออันนั้นดี? เมื่อพูดถึงซอฟต์แวร์ ETC คือตัวไกด์ (guide) ที่จะช่วยเลือกเส้นทางต่าง ๆ ได้ เช่นเดียวกับ values อื่น ๆ มันควรจะลอยอยู่แค่เบื้องหลังความคิดของคุณ และคอยสะกิดบอกทิศทางที่ถูกต้องอย่างเงียบ ๆ
แต่จะทำอย่างนั้นได้ยังไง? จากประสบการณ์ของเรา มันต้องการการตอกย้ำอย่างตั้งใจ (conscious reinforcement) ในช่วงแรก ๆ คุณอาจจะต้องใช้เวลาสักสัปดาห์หรือมากกว่านั้นคอยถามตัวเองว่า “สิ่งที่ฉันเพิ่งทำไปนี้ มันทำให้ภาพรวมระบบเปลี่ยนได้ง่ายขึ้นหรือยากขึ้นกันแน่?” ทำมันตอนคุณ save a file ทำมันตอนคุณ write a test ทำมันตอนคุณ fix a bug
มีข้อสันนิษฐานแฝง (implicit premise) ใน ETC นั่นคือมันสมมติว่าคนเราสามารถบอกได้ว่าจากหลาย ๆ ทางเลือก ทางไหนกันที่จะเปลี่ยนได้ง่ายกว่าในอนาคต ส่วนใหญ่แล้ว common sense ก็น่าจะใช้ได้ และคุณก็น่าจะพอเดาจากความรู้ที่มีได้
แต่บางครั้งคุณก็อาจจะมองไม่ออกเลยก็ได้ ซึ่งไม่เป็นไร ในกรณีนั้น เราคิดว่าคุณสามารถทำได้สองอย่าง
อย่างแรก ในเมื่อไม่แน่ใจว่าการเปลี่ยนแปลงในอนาคตจะเป็นแบบไหน คุณก็ถอยกลับไปใช้ทางเลือกที่ “เปลี่ยนง่ายที่สุด” ได้เสมอ: นั่นคือพยายามทำให้สิ่งที่คุณเขียนมันสามารถถอดเปลี่ยนได้ (replaceable) ด้วยวิธีนี้ ไม่ว่าอะไรจะเกิดขึ้นในอนาคต โค้ดส่วนนี้ก็จะไม่กลายเป็นขวากหนามขวางทาง มันอาจจะดูรุนแรงไปหน่อย แต่จริง ๆ แล้วคุณควรทำแบบนี้เป็นปกติอยู่แล้วล่ะ ซึ่งมันก็คือการรักษาให้โค้ดของคุณมีความเป็น decoupled และ cohesive นั่นเอง
อย่างที่สอง ให้มองว่านี่เป็นวิธีฝึกสัญชาตญาณ จดบันทึกสถานการณ์ลงใน Engineering Daybook ของคุณ: ว่าคุณมีทางเลือกอะไรบ้าง และคาดการณ์เกี่ยวกับการเปลี่ยนแปลงไว้อย่างไร ทิ้ง tag ไว้ในซอร์สโค้ด แล้วหลังจากนั้น เมื่อถึงเวลาที่โค้ดนี้ต้องถูกเปลี่ยน คุณจะสามารถย้อนกลับมาดูและให้ feedback กับตัวเองได้ ซึ่งมันอาจจะช่วยคุณได้ในครั้งต่อไปที่คุณต้องเจอกับทางแยก (fork in the road) ที่คล้ายกัน
เนื้อหาส่วนที่เหลือในบทนี้จะมีไอเดียเฉพาะเจาะจงเกี่ยวกับการออกแบบ แต่ทั้งหมดนั้นล้วนมีแรงผลักดันมาจากหลักการข้อเดียวนี้ทั้งสิ้น
หัวข้อที่เกี่ยวข้อง
-
Topic 9, _DRY—The Evils of Duplication_
-
Topic 10, _Orthogonality_
-
Topic 11, _Reversibility_
-
Topic 14, _Domain Languages_
-
Topic 28, _Decoupling_
-
Topic 30, _Transforming Programming_
-
Topic 31, _Inheritance Tax_
ความท้าทาย
-
ลองนึกถึง design principle ที่คุณใช้เป็นประจำดูว่า มันถูกออกแบบมาเพื่อทำให้สิ่งต่างๆ เปลี่ยนได้ง่ายขึ้น (easy-to-change) หรือเปล่า?
-
ลองนึกถึงภาษาและกระบวนทัศน์การเขียนโปรแกรม (programming paradigms) ต่าง ๆ ด้วย (เช่น OO, FP, Reactive และอื่น ๆ) มีอันไหนที่มีข้อดีหรือข้อเสียอย่างมากในการช่วยให้คุณเขียนโค้ดแบบ ETC บ้างไหม? หรือมีอันไหนที่มีทั้งสองอย่างเลยหรือเปล่า?
ในขณะที่เขียนโค้ด คุณสามารถทำอะไรได้บ้างเพื่อกำจัดข้อเสียและดึงข้อดีออกมาให้เด่นชัดขึ้น?[13]
- Editor หลายตัวรองรับการรันคำสั่งเมื่อคุณกดบันทึกไฟล์ (ไม่ว่าจะ built-in มาให้เลยหรือผ่าน extension) ลองตั้งค่าให้ Editor ของคุณแสดงข้อความ "ETC?" ขึ้นมาทุกครั้งที่คุณกดบันทึกดู[14] เพื่อใช้เป็นเครื่องเตือนสติให้ฉุกคิดถึงโค้ดที่คุณเพิ่งเขียนไปว่า มันเปลี่ยนได้ง่าย (easy to change) หรือเปล่า?