Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

Refactoring: Decompose Conditional

บทความนี้อธิบายเทคนิค Refactoring ที่ชื่อว่า "Decompose Conditional" ซึ่งเป็นการแยก Conditional Statement ที่ซับซ้อนออกเป็น Function ย่อยๆ เพื่อให้โค้ดอ่านง่ายข...

Refactoring: Decompose Conditional

ในบทความที่แล้ว เราได้เรียนรู้เทคนิค "Introduce Parameter Object" เพื่อจัดการกับฟังก์ชันที่มี Parameter จำนวนมาก คราวนี้เราจะมาดูอีกหนึ่งเทคนิค Refactoring ที่สำคัญไม่แพ้กัน นั่นคือ "Decompose Conditional" หรือการแยก Conditional ที่ซับซ้อนออกเป็น Function ย่อย เทคนิคนี้จะช่วยให้โค้ดของเราอ่านง่ายขึ้น เข้าใจง่ายขึ้น และบำรุงรักษาง่ายขึ้นอย่างมาก

ปัญหาของ Conditional ที่ซับซ้อน

ลองจินตนาการถึงฟังก์ชันที่มี Conditional Statement ที่ยาวเหยียด เต็มไปด้วย if, else if, และ else ที่ซ้อนกันไปมา การอ่านและทำความเข้าใจโค้ดแบบนี้เป็นเรื่องยากมาก นอกจากนี้ การแก้ไขหรือเพิ่มเงื่อนไขใหม่ๆ ก็อาจทำให้เกิดข้อผิดพลาดได้ง่าย

ตัวอย่าง:

function calculateShippingCost($orderTotal, $shippingZone, $isExpress) {
  $shippingCost = 0;

  if ($orderTotal > 100) {
    $shippingCost = 0; // จัดส่งฟรีสำหรับยอดสั่งซื้อเกิน 100 บาท
  } else {
    if ($shippingZone == 'domestic') {
      if ($isExpress) {
        $shippingCost = 50; // จัดส่งด่วนในประเทศ
      } else {
        $shippingCost = 30; // จัดส่งปกติในประเทศ
      }
    } elseif ($shippingZone == 'international') {
      if ($isExpress) {
        $shippingCost = 150; // จัดส่งด่วนต่างประเทศ
      } else {
        $shippingCost = 100; // จัดส่งปกติต่างประเทศ
      }
    } else {
      $shippingCost = 999; // เขตการจัดส่งไม่ถูกต้อง
    }
  }

  return $shippingCost;
}

จากตัวอย่างข้างต้น เราจะเห็นว่า Conditional Statement ซับซ้อนมาก การทำความเข้าใจว่าฟังก์ชันนี้ทำงานอย่างไรต้องใช้เวลาพอสมควร และหากต้องการเพิ่มเงื่อนไขใหม่ (เช่น โปรโมชั่นพิเศษ) โค้ดก็จะยิ่งซับซ้อนขึ้นไปอีก

การแยก Conditional Branch เป็น Function

เทคนิค "Decompose Conditional" คือการแยกแต่ละ Conditional Branch (หรือแต่ละส่วนของ if, else if, และ else) ออกเป็น Function ย่อยๆ ที่มีความหมายชัดเจน ซึ่งจะช่วยให้โค้ดหลักของเราสั้นลง อ่านง่ายขึ้น และเข้าใจง่ายขึ้น

ขั้นตอนการ Refactor:

  1. ระบุ Conditional Statement ที่ซับซ้อน
  2. สร้าง Function ย่อยสำหรับแต่ละ Conditional Branch โดยตั้งชื่อให้สื่อถึงสิ่งที่ Branch นั้นทำ
  3. แทนที่ Conditional Branch ในโค้ดหลักด้วยการเรียก Function ย่อย

ตัวอย่าง: Refactor โค้ดเดิม

function calculateShippingCost($orderTotal, $shippingZone, $isExpress) {
  if ($orderTotal > 100) {
    return calculateFreeShipping();
  } else {
    if ($shippingZone == 'domestic') {
      return calculateDomesticShipping($isExpress);
    } elseif ($shippingZone == 'international') {
      return calculateInternationalShipping($isExpress);
    } else {
      return calculateInvalidShippingZone();
    }
  }
}

function calculateFreeShipping() {
  return 0; // จัดส่งฟรีสำหรับยอดสั่งซื้อเกิน 100 บาท
}

function calculateDomesticShipping($isExpress) {
  if ($isExpress) {
    return 50; // จัดส่งด่วนในประเทศ
  } else {
    return 30; // จัดส่งปกติในประเทศ
  }
}

function calculateInternationalShipping($isExpress) {
  if ($isExpress) {
    return 150; // จัดส่งด่วนต่างประเทศ
  } else {
    return 100; // จัดส่งปกติต่างประเทศ
  }
}

function calculateInvalidShippingZone() {
  return 999; // เขตการจัดส่งไม่ถูกต้อง
}

ข้อสังเกต: โค้ดหลักใน calculateShippingCost สั้นลงและอ่านง่ายขึ้นมาก เราสามารถเข้าใจการทำงานของฟังก์ชันได้ง่ายขึ้นโดยไม่ต้องลงรายละเอียดในแต่ละ Conditional Branch

การทำให้ Code อ่านง่ายขึ้น

ถึงแม้ว่าโค้ดข้างต้นจะดีขึ้น แต่เรายังสามารถปรับปรุงให้ดีขึ้นได้อีก โดยเฉพาะอย่างยิ่งในส่วนของ calculateDomesticShipping และ calculateInternationalShipping ที่ยังมี Conditional Statement อยู่ภายใน เราสามารถใช้เทคนิค "Decompose Conditional" ซ้ำได้อีกครั้ง

ตัวอย่าง: Refactor เพิ่มเติม

function calculateShippingCost($orderTotal, $shippingZone, $isExpress) {
  if ($orderTotal > 100) {
    return calculateFreeShipping();
  } else {
    if ($shippingZone == 'domestic') {
      return calculateDomesticShipping($isExpress);
    } elseif ($shippingZone == 'international') {
      return calculateInternationalShipping($isExpress);
    } else {
      return calculateInvalidShippingZone();
    }
  }
}

function calculateFreeShipping() {
  return 0;
}

function calculateDomesticShipping($isExpress) {
  return $isExpress ? calculateDomesticExpressShipping() : calculateDomesticRegularShipping();
}

function calculateInternationalShipping($isExpress) {
  return $isExpress ? calculateInternationalExpressShipping() : calculateInternationalRegularShipping();
}

function calculateDomesticExpressShipping() {
  return 50;
}

function calculateDomesticRegularShipping() {
  return 30;
}

function calculateInternationalExpressShipping() {
  return 150;
}

function calculateInternationalRegularShipping() {
  return 100;
}

function calculateInvalidShippingZone() {
  return 999;
}

ข้อดีของการ Refactor:

  • Code Readability: โค้ดอ่านง่ายขึ้นมาก แต่ละฟังก์ชันมีหน้าที่ชัดเจน
  • Maintainability: การแก้ไขหรือเพิ่มเงื่อนไขใหม่ๆ ทำได้ง่ายขึ้น เพราะเราสามารถแก้ไขเฉพาะ Function ที่เกี่ยวข้องได้
  • Testability: การเขียน Unit Test สำหรับแต่ละ Function ทำได้ง่ายขึ้น
  • Reusability: Function ย่อยๆ สามารถนำไปใช้ซ้ำในส่วนอื่นๆ ของโปรแกรมได้

กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย

กรณีใช้งานจริง:

  • ระบบคำนวณภาษี: การคำนวณภาษีอาจซับซ้อนขึ้นอยู่กับประเภทสินค้า, สถานที่จัดส่ง, และโปรโมชั่นต่างๆ การใช้ "Decompose Conditional" จะช่วยให้โค้ดคำนวณภาษีอ่านง่ายและบำรุงรักษาง่าย
  • ระบบจัดการสิทธิ์การเข้าถึง: การตรวจสอบสิทธิ์การเข้าถึงอาจมีหลายเงื่อนไข เช่น สิทธิ์ของผู้ใช้, กลุ่มของผู้ใช้, และทรัพยากรที่ต้องการเข้าถึง การใช้ "Decompose Conditional" จะช่วยให้โค้ดตรวจสอบสิทธิ์อ่านง่ายและเข้าใจง่าย

ข้อผิดพลาดที่พบบ่อย:

  • การแยก Conditional Branch ที่ไม่เหมาะสม: ควรแยก Conditional Branch ที่มีความหมายชัดเจนและเป็นอิสระต่อกัน หาก Conditional Branch มีความสัมพันธ์กันอย่างใกล้ชิด อาจไม่จำเป็นต้องแยก
  • การตั้งชื่อ Function ที่ไม่สื่อความหมาย: ควรตั้งชื่อ Function ให้สื่อถึงสิ่งที่ Function นั้นทำอย่างชัดเจน เพื่อให้โค้ดอ่านง่ายและเข้าใจง่าย
  • การไม่ทดสอบโค้ดหลัง Refactor: หลังจาก Refactor โค้ดแล้ว ควรทดสอบโค้ดอย่างละเอียดเพื่อให้แน่ใจว่าโค้ดยังทำงานได้อย่างถูกต้อง

สรุป

เทคนิค "Decompose Conditional" เป็นเครื่องมือที่มีประสิทธิภาพในการปรับปรุงโค้ดที่มี Conditional Statement ที่ซับซ้อน การแยก Conditional Branch ออกเป็น Function ย่อยๆ จะช่วยให้โค้ดอ่านง่ายขึ้น เข้าใจง่ายขึ้น บำรุงรักษาง่ายขึ้น และเพิ่มความยืดหยุ่นในการแก้ไขหรือเพิ่มเงื่อนไขใหม่ๆ อย่าลืมนำเทคนิคนี้ไปประยุกต์ใช้กับโปรเจกต์ PHP ของคุณ เพื่อให้โค้ดของคุณสะอาดและมีคุณภาพมากยิ่งขึ้น

ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับการใช้ Environment Variables ด้วย .env เพื่อจัดการค่า Configuration ต่างๆ ของ Application ของเรา

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service