Refactoring or Refucktoring
เริ่มกันที่เรามารู้จักความหมายของ Refactoring จาก refactoring.com
Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
แปลว่าอะไรนะ?
เทคนิคในการปรับโครงสร้างโค้ดเดิมที่มีอยู่ให้เป็นแบบใหม่ที่มีระเบียบมากขึ้น โดยเปลี่ยนแค่โครงสร้างของโค้ด แต่ไม่ได้เปลี่ยนพฤติกรรม
Motivation
หลังจากดู YOW! Lambda Jam 2019 — Bartosz Milewski — A Taste of Type Theory และติดใจเสื้อแกมากๆ โดยสิ่งที่น่าสนใจคือ ตัวอย่างที่แกได้ยกขึ้นมาในเรื่อง Isomorphism โดยการ cheat เรื่อง Equality ไว้ก่อน ซึ่งสิ่งที่น่าสนใจคือคำว่า Equality และประกอบกับช่วงนี้ได้ผ่านประสบการณ์อันโหดร้ายมา เลยตัดสินใจเขียนเรื่องนี้
Basics
สำหรับพื้นฐานที่ต้องรู้นี้คือเรื่องของ Isomorphism โดย Bartosz Milewski ได้ยกตัวอย่างในเรื่องของ Type isomorphism ดังนี้ ((), a) ~ a
lu :: forall a. ((), a) -> a
lu ((), x) = x
lu_inv :: forall a. a -> (() -> a)
Get Uncle Quin’s stories in your inbox
Join Medium for free to get updates from this writer.
lu_inv x = ((), x)
โดยให้เรามอง () unit type เป็น เลข 1 ใน 1 * a = a แทนก่อนก็ได้ แล้วจะเห็นว่า 1 หรือ () เป็น Identity Element เพราะว่าเมื่อเรานำ function lu กับ funcion lu_inv มา composition กันเราจะได้ Identity Function
lu . lu_inv = id
lu_inv . lu = id
สิ่งนี่มัน Proof ว่ามันมึความเท่าเทียมกัน (equivalence) นั่นเอง แต่ออกแนว cheat หน่อยๆ
หมายเหตุ* นิยามของ Equlity มองถึงความเท่ากันในมุมมองของ context ด้วย ไม่ได้มองถึงแค่ผลลัพธ์เท่านั้น ขยายความคือคุณสามารถที่จะ replace A ด้วย B ได้ ถ้าสิ่งนั้นมีความหมายเดียวกันจริงๆ เช่น x = x
Playing with word “Refactoring”
แล้วมันเกี่ยวอะไรกับ Refactoring นะ?
ถ้าให้พูดอย่างง่าย สมมติเรามีของอยู่สองสิ่ง เราจะ Proof ได้อย่างไรว่า “มันมีความเท่าเทียมกัน”
ถ้าจุดประสงค์ของ Refactoring คือการเปลี่ยนโครงสร้างของโค้ด แต่ไม่เปลี่ยนพฤติกรรม แล้วเรามองว่า โค้ดก่อนเปลี่ยนคือ A และโค้ดหลังเปลี่ยนคือ B โดย A และ B ต้อง Equivalence กันในแง่ของพฤติกรรม แต่เราเปลี่ยนโครงสร้างของโค้ดไปแล้ว เรามั่นใจได้อย่างไรว่าพฤติกรรมมันเหมือนเดิมนะ
แน่นอนว่าหลายๆคนคงเคยได้ยิน TDD (Test Driven Development) กันมาแล้ว แน่นอนว่า Test ที่สามารถให้ Machine execute ได้ ถือเป็นวิธีการ Proof ว่าเราสามารถเปลี่ยนโครงสร้างของโค้ดได้ โดยที่พฤติกรรมยังคงเหมือนเดิมอยู่ จึงไม่แปลกที่หลักการของ TDD จึงมีคำว่า Refactor ผสมอยู่นั่นเอง
อย่างไรก็ตามเรามักจะเจอโจทย์ของการรับทำซอฟต์แวร์ต่อจากทีมอื่นๆ ซึ่งมักจะไม่มี Test ดังนั้นการที่เราจะทำการเปลี่ยนแปลงโครงสร้างของโค้ด เราต้องทำแบบทดสอบเพื่อหาพฤติกรรมของโครงสร้างโค้ดชุดนั้นก่อน (Characteristic Test) เพื่อที่เราจะสามารถ Proof ได้ว่า โค้ดก่อนการเปลี่ยนแปลงโครงสร้างกับ หลังการเปลี่ยนแปลงโคร้างสร้างนั้นให้ผลลัพธ์ที่เป็นพฤติกรรมที่คงเดิม
ไม่เช่นนั้นแล้ว เวลาเราแก้โด้ดโดยที่เราไม่สามารถพิสูจน์ได้ว่ามัน Equivalence กัน แปลว่าเราไม่ได้ Refactoring อยู่นะ แต่เรากำลังทำ Refucktoring อยู่ต่างหาก
บทความหน้าอาจจะพบกับเรื่อง TDD (Test Driven Development) เมื่อพูดถึงสิ่งนี้ก็พบว่ามีสิ่งที่น่าสนใจใน YOW! Lambda Jam 2019 — Bartosz Milewski — A Taste of Type Theory คือ Induction rule กับ Elimination (Primitive recursion) เราลองนำมาอธิบาย TDD ด้วยสองสิ่งนี้ น่าจะสนุกนะ










