เป้าหมายของการ refactoring คือการปรับเปลี่ยนโครงสร้าง (structure) ของโปรแกรม เพื่อสนับสนุนให้เราปรับเปลี่ยนพฤติกรรม (behavior) ได้ง่าย คำถามคือแล้วเราควรจะ refactoring ตอนไหนดี? เวลาไหนถึงจะเหมาะสม ที่นี่มีคำตอบให้ครับ
Never (ไม่ต้องทำ)
ถ้าเราคิดว่าไม่มีโอกาสที่จะต้องมาแก้ไข เพิ่มเติม พฤติกรรมของโปรแกรม ก็ไม่มีความจำเป็นต้อง refactor เลย
บางระบบที่เป็น static system เราใช้กฎว่า “ถ้ามันไม่พัง ก็ไม่ต้องแก้”
Later (ทำทีหลัง)
หลายคนเจอว่างานที่ทำอยู่ไม่มีเวลา ไว้ค่อยมา refactor ตอนหลังแล้วกัน
แต่ไว้ตอนหลัง ไว้ก่อน นี่มันตอนไหนกันนะ 1 วัน? 1 เดือน? 1 ปี? หรือไม่มีอีกเลย?
ลองเปลี่ยนคำถามใหม่กับตัวเอง จาก “เรามีเวลามาทำให้โค้ดนี้ดีขึ้นไหมนะ” ซึ่งหลายครั้งจะตอบว่าไม่มี ลองเปลี่ยนเป็น “เราจะทำอะไรต่างออกไปจากเดิม ถ้าเรามีเวลาล่ะ” — ถ้าเราเปลี่ยนความคิด ความเชื่อ การกระทำก็จะเปลี่ยนตาม
- ลอง list รายการที่คิดว่าจะแก้ออกมาก่อน ← หลายครั้งที่เราบอกค่อยกลับมาแก้ แต่เราไม่ได้มี memo เลย ว่าอะไรบ้างที่แก้ จะแก้ตอนไหน ทำให้เราก็ละเลยไปด้วยงานที่เร่ง
- คิดซะว่าเป็น fun list รายการที่หาอะไรสนุก ๆ ทำกัน
- หาเศษเวลา บางครั้งเราไปเจองานใหญ่ ๆ ที่ stuck แก้ไม่ได้สักที กำลังใจเราก็น้อยลง ก็อยากจะพักซักหน่อยใช่ไหม? แต่ ก็อยากทำงานอยู่ ลองหยิบ fun list ข้อก่อนหน้ามาทำดูโดยใช้เศษเวลาก่อนไปเริ่มงานใหญ่ เศษเวลาอาจะเป็น 20 นาที 30 นาที หรือ 1 ชั่วโมงก็ได้ ไม่ต้องทำให้ครบทั้ง fun list ก็ได้ แต่เห็นไหม เราเริ่มมี progress บ้างแล้ว 😀
ทำไมควรมา refactor later
- ลองคิดว่าเป็นเหมือนภาษีที่ต้องจ่ายก็ได้ ทุกอย่างขึ้นอยู่กับมุมมอง - ลองคิดว่าทุกครั้งที่มีต้องไปแก้งาน ก็หาโอกาสสัก 10-20% มาปรับปรุงโค้ดให้ดีขึ้นไปด้วยเลย
- จัดลำดับความสำคัญ ลองดูว่าใน fun list มีส่วนไหนที่มีโอกาสต้องมาแก้ แล้วค่อย ๆ ทำวันนี้ให้ดีกว่าเมื่อวาน ไม่ใช่ต้องทำทุกอย่างใน fun list ซะหน่อย นี่คือเรากำลังทำงานสำคัญที่ไม่เร่งด่วนอยู่ เพื่อที่มันจะไม่กลายเป็นสำคัญและเร่งด่วน
- ช่วยให้เรามีเวลาเรียนรู้ สิ่งสำคัญในการทำ software design ที่ดี ไม่ใช่แค่การเริ่มต้นสร้างโครงสร้างที่ดีตั้งแต่ต้น นั่นแค่ส่วนหนึ่ง แต่จะมีสักกี่ครั้งที่ได้ขึ้น project ใหม่ ลองปรับจากของที่มีอยู่แล้วดูซิ โค้ดระดับ 5 ปี 10 ปี 20 ปี เราจะทำให้มันดีขึ้นยังไงได้บ้าง
เริ่มต้นจากทำอะไรสนุก ๆ และได้เรียนรู้ไปด้วย ช่วยให้เราสนุกและเราจะทำงานได้ดีกว่าเดิมมาก
ดังนั้นเรารู้อย่างนี้จะมาบอกว่า later is never ไม่ได้ละนะ
After (ทำหลังแก้โค้ด)
บางครั้งเรามีความจำเป็นต้องไปแก้โค้ดเพื่อเปลี่ยนพฤติกรรม (behavior) แถมโค้ดตรงนั้นก็รกน่าดู
แต่ตอนนั้นยังมองภาพไม่ออกว่าจะ refactor ยังไงดี
งั้นเราแก้โค้ดไปทั้งที่ยังรกเนี่ยแหละ ซึ่งก็ดี แต่พอแก้เสร็จแล้ว เราก็พอจะเริ่มมีไอเดียละว่าจะ refactor ยังไงต่อ คำถามคือเราจะ refactor ‘หลัง’ จากนั้นเลยไหม
คำตอบคือ it depends.. (lol ตอบแบบปาหมอนชัด ๆ)
เอ.. แล้วมัน depends on อะไรล่ะ ลองมาดูเหตุผลที่ควร refactor after กัน
- คิดว่าต้องกลับมาแก้โค้ดในเร็ว ๆ นี้ไหม ถ้าคำตอบคือ “ใช่” และมันทำให้การแก้ครั้งหน้าง่ายขึ้นด้วย
- ความรู้เกี่ยวกับโค้ดตรงนั้นยังสดใหม่ สมองเราลืมได้ง่ายมาก ขนาด daily วันจันทร์ว่าศุกร์ที่แล้วทำอะไรยังลืมได้ง่าย ๆ เลย และยิ่งปล่อยไว้นาน โค้ดตรงนั้นอาจจะถูกแก้ไปหลายต่อหลายมือ จนท่าที่เราคิดว่าจะ refactor อาจจะทำได้ยากขึ้น
- สัดส่วนการแก้ระหว่าง structure และ behavior ต่างกันแค่ไหน
- ใช้เวลา 1 ชม. refactor และอีก 1 ชม. เพิ่ม feature อาจสมเหตุสมผล
- แต่… ใช้เวลา 1 สัปดาห์ refactor กับ 1 ชม. เพิ่ม feature อาจไม่เหมาะ ถ้าต้องใช้เวลาขนาดนั้น ให้เปลี่ยนเป็น refactor later แทน
First (ทำก่อน)
ควร refactor ก่อนเริ่มงานไหม?
It depends.. (มาอีกละคำตอบนี้)
อะ งั้นมาดูว่ามัน depends on อะไร
- ถ้าเรา refactor ก่อนมันทำให้เราแก้โค้ดง่ายขึ้นไหม ถ้าไม่ได้ทำให้เราทำงานง่ายขึ้นก็อย่าพึ่ง refactor
- ทำให้เราเข้าใจโค้ดดีขึ้นไหม? เราจะใช้เทคนิคที่ชื่อ read by refactoring เช่น ระหว่างที่เราแก้ชื่อตัวแปรให้อ่านง่าย เราก็เข้าใจโค้ดบริเวณนั้นไปด้วย ตัวอย่าง
js1// before 2let temp = data.map((x) => x.n); 3 4// after 5let userNames = users.map((user) => user.name); 6
- คุ้มค่าไหม?
- ก็ต้องมาดูว่า เรามีโอกาสมาแก้อีกไหม ถ้าไม่มี กลับไปดู Never
- ถ้ามีโอกาสกลับมาแก้บ่อย ทุกสัปดาห์ไปอีกเป็นปี โอ้! งั้น refactor ก็น่าจะคุ้มอยู่นะ
- หลีกเลี่ยงการเดา ไม่งั้น refactor จะกลายเป็นเป้าหมายในตัวเอง เพราะเราไม่ได้ refactor เพื่อที่ refactor งงมะ? เรา refactor เพื่อที่เราจะแก้ bug หรือเพิ่ม feature ง่ายขึ้น ต่างหาก
- แบบไหนไม่เดา? เช่น ตอนนี้รู้สึกสับสนมากหลังจากอ่านโค้ดตรงนี้ refactor จะช่วยให้ตัวชั้นเอง เข้าใจโค้ดมากขึ้น
สุดท้ายการ refactor ก็เหมือนการลงทุน แต่เป็นการลงทุนที่ low risk, high reward
เพราะเราวางแผนไว้ทุกอย่างแล้วถึงการ refactor ครั้งนั้นจะไม่คุ้มค่าอย่างที่คิด เราก็เสียเวลาไปนิดเดียว
ตารางสรุป
| สถานการณ์ | ควรทำเมื่อไหร่? | ทำไมถึงควรทำ? | คำแนะนำ | |
|---|---|---|---|---|
| Never | เมื่อโค้ด/ระบบนั้นไม่จำเป็นต้องแก้ไขอีกในอนาคต (Static System) | ถ้ามันไม่พัง ก็ไม่ต้องแก้ ประหยัดเวลาไปทำสิ่งที่สำคัญกว่า | ประเมินให้ดีว่า "ไม่มีโอกาสแก้ไข" จริงๆ | |
| Later | เมื่อเจอโค้ดที่ควรปรับปรุง แต่ยังไม่ว่างทำ หรือยังไม่กระทบงานด่วน | เพื่อไม่ให้กลายเป็นงานด่วนและสำคัญในอนาคต และเป็นโอกาสในการเรียนรู้ | - สร้าง Fun List สิ่งที่อยากแก้ - ใช้เศษเวลา 20-30 นาทีทำ - คิดเหมือนเป็น "ภาษี" 10-20% ที่ต้องจ่ายเพื่อปรับปรุงโค้ด | |
| After | หลังจากเพิ่มฟีเจอร์หรือแก้บั๊กในโค้ดส่วนนั้นเสร็จ | ความรู้เกี่ยวกับโค้ดยังสดใหม่ และเห็นแนวทางการปรับปรุงที่ชัดเจนขึ้นแล้ว | - ทำทันทีถ้าคิดว่าจะได้กลับมาแก้เร็วๆ นี้ - สมดุลเวลา: Refactor 1 ชม. / เพิ่ม Feature 1 ชม. (สมเหตุสมผล) | |
| First | ก่อนเริ่มแก้ไขโค้ดที่ซับซ้อนหรืออ่านยาก | เพื่อให้การเพิ่มฟีเจอร์/แก้บั๊กในขั้นตอนต่อไปทำได้ง่ายขึ้นและเร็วขึ้น | - ทำเมื่อมันช่วยให้ทำงานง่ายขึ้นจริงๆ - ใช้เทคนิค "Read by Refactoring" (เช่น เปลี่ยนชื่อตัวแปร) เพื่อทำความเข้าใจโค้ด |
Flowchart การ refactor
when to refactor (flowchart)