เราจะเขียนโค้ดที่ต่อยอดยากไปทำไม ?

Tae Keerati Jearjindarat
2 min readOct 1, 2020

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

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

เราเริ่มพัฒนา Feature ใหม่ยังไง

คำถามง่าย ๆ : ณ วันนี้เรารับ requirement มาแล้วลงโค้ดเลยรึเปล่า ?

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

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

สิ่งเหล่านี้สำคัญกับการออกแบบโดยที่เราจะต้องเขียนโปรแกรมให้ถูกต้องตามความต้องการ และส่งมอบได้ถูกต้องครับ ถ้าเราไม่ถาม และคิดไปเอง เป็นไปได้ยากที่จะถูก Spec ซึ่งนอกจากจะช่วยให้เราทำถูกต้องแล้ว ยังช่วยตอนเรา ออกแบบ ซอฟต์แวร์ด้วยเพราะจะทำให้เรามี Concerns ต่างๆ เกิดขึ้นซึ่งส่งผลต่อการเขียนโปรแกรมทั้งหมด วันนี้ผมจะพูดถึงการออกแบบเพื่อต่อยอดและสานต่อได้ง่ายวิธีหนึ่งจาก SOLID Principles ที่ผมคิดว่าเป็นหลักการที่ดีช่วยในการออกแบบในกรณีที่เจอ Requirements คลุมเครือ ไม่ชัดเจนและมีแววว่าจะต้องทำเพิ่มหรือแก้บ่อยครับ

เราควรเขียนโค้ด เพื่อให้ต่อยอดได้ง่าย ๆ

เป็นสิ่งที่ผมใฝฝันมาตลอดเมื่อทำงานไปถึงจุดหนึ่งแล้วเราต้องกลับมาแก้ แล้วพบว่าตัวเองทิ้งหนี้มหาศาลเอาไว้ อาจด้วยตอนนั้นงานรีบหรือคิดไม่ออกก็ไม่เป็นไร แต่ ณ วันที้ต้องกลับมาแก้ช่างทรมานเหลือเกิน

แล้ววันหนึ่งผมก็รู้จัก SOLID Principles จากรุ่นพี่ที่คณะ ที่เป็น keywords สำคัญในการพัฒนาตัวเองมาตลอดตั้งแต่อยู่ ปี 2 ที่คณะ SIT ซึ่งเริ่มต้นผมไม่เข้าใจหรอกครับว่ามันคืออะไร ได้แต่ลองอ่านก็คิดว่ามันก็เรียบง่ายดี แต่ตอนที่ควรเอาไปใช้กลับนึกไม่ออกซะงั้น ผมพัฒนาตัวเองมาเรื่อย ๆ จากการลองเขียนผิดๆๆๆๆ แล้ววันหนึ่งมันก็ถูก ซึ่งเป็นวันที่เราค่อย ๆ เข้าใจว่ามันดียังไงและทำให้ชีวิตดีขึ้นเยอะครับ

วันนี้อยากจะเขียนเน้นไปที่ Open-closed Principle จากที่เกริ่นมาตั้งแต่ต้นบล็อคว่า เขียนให้ต่อยอดง่าย เพราะหลักการนี้เป็นวิธีคิดเพื่อให้เราเขียนโปรแกรมสำหรับต่อยอดจริง ๆ เพราะตัว concept เขียนไว้ง่ายมาก

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

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

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

จากหลักการนี้มันดูเหมือนจะสร้างปัญหาให้เรานิดนึง
แต่คำถามคือเราจะทำยังไงให้ต่อยอดได้ล่ะ ?

เมื่อมีปัญหาเราลองมาใช้ Design Pattern ได้ไหม ?

จากที่เล่ามาก็ยังไม่เจอวิธีที่ดีที่สุด แต่มีวิธีหนึ่งที่อยากมาแชร์คือการใช้ Design Pattern มาหลักๆ ตอนออกแบบจะพยายามใช้ Pattern ที่ชื่อว่า Strategy Pattern ในการออกแบบเนื่องจากตรงกับคอนเซปของ Open-closed principle พอดี และยังเข้ากับ Requirement ที่มี Business Logic แปลกๆ และได้รับมาทำอยู่บ่อย ๆ

Strategy Pattern

วิธี Implement ก็ง่าย ๆ ครับคือมี Class Interface 1 ตัวเพื่อกำหนดว่าเราจะต้องมี method อะไรบ้างที่สำคัญ เป็นการกำหนดว่าเราจะมี Strategy อะไร เหมือนตัวอย่างคือเรามีแอปนำทาง (Class Navigator เรียกว่า Context) ที่สามารถนำทางได้หลายแบบ (RouteStrategy) เช่น นำทางทางถนนใหญ่ (RoadStrategy) นำทางด้วยขนส่งสาธารณะ (PublicTransportStrategy) และนำทางด้วยการแนะนำการเดิน (WalkingStrategy) ซึ่งการนำทางแต่ละแบบก็คือ Strategy หนึ่งที่มี Business Logic แตกต่างกัน วิธีการนำไปใช้จริงก็สามารถทำได้หลายเทคนิค แต่ง่ายที่สุดคือการสร้าง Object นั้นใน Context โดยกำหนด Type ด้วย Interface จะทำให้สามารถใช้ method นั้นได้โดยเปลี่ยน Implementation ไปเรื่อย ๆ ตาม เงื่อนไขที่เรากำหนด

ภาพจากเว็บ https://refactoring.guru/design-patterns/strategy

Design Pattern นี้เข้าทางกับ Open-closed Principle โดยเมื่อเรามี Business Logic ใหม่ แต่ยังเป็น Feature เดิม เราสามารถ Implement Strategy นั้นได้เลยโดยที่ไม่ต้องไปแก้ของเก่า (Closed for modification) และง่ายต่อการต่อยอดโดยเพิ่ม Strategy (Open for extension) เป๊ะ ๆ ซึ่งเราสามารถเพิ่ม Feature ได้อย่างง่ายและง่ายต่อการดูแลรักษาด้วยครับ

นอกจากตัวอย่างจากเว็บ Refactoring guru จริง ๆ ใน Real World เราสามารถนำไปใช้ได้หลายสถานการณ์ อย่างแอปบวกเลขที่บอกไปก็สามารถใช้ได้เช่นกัน (แต่อาจจะไม่จำเป็น) เช่น เรามีแอปสำหรับคำนวณ โดยมี Interface เป็น CalculationStrategy ที่มี method calculate ที่รับ Number 2 Parameters แล้วเรา Implement การคำนวณตามใจเรา เช่น AddStrategy สำหรับการบวกเลข หรือ DivideStrategy สำหรับการหารก็ได้ หรือแม้กระทั้งการปรับ Algorithm ต่าง ๆ เช่น Sort Algorithm / Search Algorithm

สุดท้ายนี้

Open-closed Principle เป็นหนึ่งในหลักการที่ช่วยเพิ่มความสามารถในการ Maintainability ให้กับระบบด้วย อ่านเพิ่มเติมได้ที่ การค้นพบความรู้ใหม่กับเรื่อง Maintainability

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

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

ขอบคุณทาง depa และ คณะเทคโนโลยีสารสนเทศ มจธ.
ที่มอบทุนการศึกษาเพชรพระจอมเกล้าเพื่อพัฒนาเทคโนโลยีและนวัตกรรมดิจิทัล และทำให้ได้โอกาสหาความรู้สำหรับการทำงานจริงครับ

ขอบคุณพี่ชาร์ปที่พาผมไปรู้จักกับ Strategy Pattern และทำให้เห็นประโยชน์และทำให้ได้ใช้เรืี่อย ๆ ในงานจริงครับ

เรื่องต่อไปจะเป็นเรื่องอะไร ติดตามกันต่อไป ขอบคุณที่อ่านจนจบครับ 🙏

--

--

Tae Keerati Jearjindarat

Hi, I'm Tae, Associate Engineering Manager at LINEMAN Wongnai. Thanks for following <3