Sitemap

Refactoring or Refucktoring

2 min readApr 7, 2020

--

Press enter or click to view image in full size
Photo by Sharon McCutcheon on Unsplash

เริ่มกันที่เรามารู้จักความหมายของ 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 ด้วยสองสิ่งนี้ น่าจะสนุกนะ

--

--

Uncle Quin
Uncle Quin

Written by Uncle Quin

Bit Crafter / Philosopher of the Void