Refactoring: Replace Magic Number with Symbolic Constant
ในบทความก่อนหน้า เราได้เรียนรู้วิธีการใช้ Xdebug Profiler เพื่อวัดประสิทธิภาพของโค้ดและค้นหาจุดที่เป็นคอขวด (bottleneck) ในแอปพลิเคชันของเรา เมื่อเราพบจุดที่ต้องปรับปรุงแล้ว ขั้นตอนต่อไปคือการปรับปรุงโค้ดให้มีประสิทธิภาพและอ่านง่ายขึ้น ในบทความนี้ เราจะมาเรียนรู้วิธีการ Refactoring โค้ดโดยการแทนที่ "Magic Number" ด้วย "Symbolic Constant" ซึ่งเป็นเทคนิคพื้นฐานแต่ทรงพลังที่จะช่วยให้โค้ดของคุณสะอาดและบำรุงรักษาได้ง่ายขึ้น
ปัญหาของ Magic Number
Magic Number คืออะไร? Magic Number คือตัวเลขที่ปรากฏในโค้ดโดยไม่มีคำอธิบายว่าตัวเลขนั้นหมายถึงอะไร หรือมีที่มาอย่างไร ตัวอย่างเช่น:
function calculateDiscount($price) {
if ($price > 100) {
return $price * 0.1; // ลดราคา 10% ถ้าซื้อเกิน 100
} else {
return 0;
}
}
ในตัวอย่างนี้ 100 และ 0.1 คือ Magic Number เพราะเราไม่รู้ว่า 100 หมายถึงอะไร (จำนวนเงินขั้นต่ำ?) และ 0.1 หมายถึงอะไร (อัตราส่วนลด?) การใช้ Magic Number ทำให้เกิดปัญหาดังนี้:
- อ่านยาก: คนที่อ่านโค้ดจะไม่เข้าใจความหมายของตัวเลขทันที
- บำรุงรักษายาก: ถ้าเราต้องการเปลี่ยนค่าของตัวเลข เราต้องค้นหาทุกที่ที่ตัวเลขนั้นปรากฏและแก้ไข ซึ่งอาจทำให้เกิดข้อผิดพลาดได้
- มีความเสี่ยงที่จะเกิดข้อผิดพลาด: หากเราพิมพ์ตัวเลขผิดพลาดในที่ใดที่หนึ่ง โค้ดอาจทำงานไม่ถูกต้อง
การสร้าง Constant
Constant คือค่าคงที่ที่ไม่สามารถเปลี่ยนแปลงได้หลังจากที่ถูกกำหนดค่าแล้ว ใน PHP เราสามารถสร้าง Constant ได้สองวิธีหลักๆ คือ:
- ใช้ฟังก์ชัน
define(): - ใช้ keyword
const(ตั้งแต่ PHP 5.3):
define("MINIMUM_PRICE_FOR_DISCOUNT", 100);
define("DISCOUNT_RATE", 0.1);
const MINIMUM_PRICE_FOR_DISCOUNT = 100;
const DISCOUNT_RATE = 0.1;
ข้อแตกต่างระหว่าง define() และ const:
define()สามารถใช้ได้ทุกที่ในโค้ด (รวมถึงภายใน function)constต้องใช้ภายใน namespace หรือ class เท่านั้นconstจะถูกกำหนดค่าใน compile time ในขณะที่define()จะถูกกำหนดค่าใน runtime
โดยทั่วไปแล้ว การใช้ const ภายใน class หรือ namespace จะเป็นที่นิยมมากกว่า เพราะช่วยให้โค้ดเป็นระเบียบและง่ายต่อการจัดการ
การใช้ Constant แทน Magic Number
เมื่อเราสร้าง Constant แล้ว เราสามารถนำ Constant เหล่านั้นมาใช้แทน Magic Number ในโค้ดของเราได้ ตัวอย่างเช่น:
const MINIMUM_PRICE_FOR_DISCOUNT = 100;
const DISCOUNT_RATE = 0.1;
function calculateDiscount($price) {
if ($price > MINIMUM_PRICE_FOR_DISCOUNT) {
return $price * DISCOUNT_RATE;
} else {
return 0;
}
}
เมื่อเราแทนที่ Magic Number ด้วย Constant แล้ว โค้ดของเราจะอ่านง่ายขึ้นมาก เพราะเราสามารถเข้าใจความหมายของตัวเลขได้ทันที นอกจากนี้ การบำรุงรักษาก็จะง่ายขึ้นด้วย เพราะถ้าเราต้องการเปลี่ยนค่าของตัวเลข เราเพียงแค่แก้ไขค่าของ Constant ที่เดียวเท่านั้น
กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย
กรณีใช้งานจริง:
สมมติว่าเรามีฟังก์ชันที่คำนวณภาษีมูลค่าเพิ่ม (VAT):
function calculateVAT($price) {
return $price * 0.07; // VAT rate is 7%
}
เราสามารถ Refactor โค้ดนี้ได้โดยการสร้าง Constant สำหรับอัตรา VAT:
const VAT_RATE = 0.07;
function calculateVAT($price) {
return $price * VAT_RATE;
}
ข้อผิดพลาดที่พบบ่อย:
- ลืมกำหนด Constant: บางครั้งเราอาจจะลืมกำหนด Constant ก่อนที่จะนำไปใช้ในโค้ด ทำให้เกิด error
- ใช้ Constant ผิดประเภท: เราควรเลือกประเภทของ Constant ให้เหมาะสมกับข้อมูล เช่น ถ้า Constant เป็นตัวเลขทศนิยม เราควรใช้
float - ตั้งชื่อ Constant ไม่สื่อความหมาย: ชื่อของ Constant ควรสื่อความหมายและบอกให้รู้ว่า Constant นั้นมีหน้าที่อะไร
สรุป
การแทนที่ Magic Number ด้วย Symbolic Constant เป็นเทคนิค Refactoring ที่ง่ายแต่มีประสิทธิภาพสูง ซึ่งจะช่วยให้โค้ดของคุณอ่านง่ายขึ้น บำรุงรักษาง่ายขึ้น และลดความเสี่ยงที่จะเกิดข้อผิดพลาด อย่าลืมนำเทคนิคนี้ไปใช้ในโปรเจกต์ PHP ของคุณ เพื่อให้โค้ดของคุณมีคุณภาพมากยิ่งขึ้น
ในบทความถัดไป เราจะมาเรียนรู้เทคนิค Refactoring อีกอย่างหนึ่งที่เรียกว่า "Introduce Parameter Object" ซึ่งจะช่วยให้เราจัดการกับพารามิเตอร์จำนวนมากในฟังก์ชันได้อย่างมีประสิทธิภาพ