ข้ามไปเนื้อหาหลัก

เจาะลึก State Pattern: จัดการโค้ดซับซ้อนเมื่อออบเจ็กต์เปลี่ยนสถานะ

ทำความเข้าใจรูปแบบการเขียนโปรแกรม State Pattern ทางแก้ปัญหาโค้ดอีคอมเมิร์ซที่เต็มไปด้วยเงื่อนไข if-else ซับซ้อน

เรียบเรียงโดย AI
Inewgen
06 Aug 2026ที่มา: Dev.to3 นาทีอ่าน (0 ครั้ง)อัปเดตล่าสุด 29 Aug 2026
แชร์
เจาะลึก State Pattern: จัดการโค้ดซับซ้อนเมื่อออบเจ็กต์เปลี่ยนสถานะ

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ขนาดตัวอักษร
  • ระบบคำสั่งซื้ออีคอมเมิร์ซมีถึง 7 สถานะ ทำให้เกิดความซับซ้อนสูง
  • State Pattern ช่วยแก้ปัญหาการใช้เงื่อนไข if ซ้อนกันหลายชั้น
  • การเพิ่มสถานะใหม่ทำได้ง่ายโดยไม่ต้องแก้โค้ดเดิมตามหลัก Open/Closed
  • สามารถต่อยอดไปเป็น State Machine ร่วมกับเฟรมเวิร์กต่างๆ ได้

ในระบบจัดการคำสั่งซื้อหรืออีคอมเมิร์ซ คำสั่งซื้อหนึ่งรายการจะต้องผ่านสถานะต่างๆ มากมาย ได้แก่ draft, pending, paid, shipped, delivered, cancelled และ refunded โดยการทำงานในแต่ละขั้นตอนจะขึ้นอยู่กับสถานะปัจจุบันเท่านั้น เช่น การชำระเงินจะทำได้ก็ต่อเมื่อสถานะเป็น pending การจัดส่งทำได้เมื่อเป็น paid และการยกเลิกจะทำได้ก็ต่อเมื่อยังไม่มีการจัดส่งเกิดขึ้น ซึ่งมักจะส่งผลให้โค้ดโปรแกรมกลายเป็นชุดคำสั่งเงื่อนไขแบบ if ($this->status === 'pending') ซ้ำๆ กันในทุกเมธอด

ปัญหาที่ตามมาคือ เมธอด cancel() ต้องคอยตรวจสอบว่าสถานะอนุญาตให้ยกเลิกได้หรือไม่ เมธอด ship() ต้องตรวจสอบการอนุญาตจัดส่ง และเมธอด refund() ต้องตรวจสอบการคืนเงิน หากมีการเพิ่มสถานะใหม่หรือเพิ่มการดำเนินการใหม่ นักพัฒนาจะต้องเข้าไปแก้ไขทุกเมธอดที่เกี่ยวข้องทั้งหมด รวมถึงการตรวจสอบทุกเงื่อนไขการเปลี่ยนผ่าน จนทำให้ความซับซ้อนพุ่งสูงขึ้นอย่างรวดเร็ว โดยคำนวณจากจำนวนสถานะคูณด้วยการดำเนินการ ซึ่งหากมี 7 สถานะและ 6 การดำเนินการ จะเท่ากับมีเงื่อนไขถึง 42 แบบที่ต้องจัดการและรักษาความสอดคล้องร่วมกัน

7สถานะคำสั่งซื้อในระบบ
6การดำเนินการหลัก
42เงื่อนไขที่ต้องจัดการ

"permette a un oggetto di alterare il proprio comportamento quando il suo stato interno cambia. L'oggetto sembrera cambiare la propria classe"

Gang of Four

เพื่อแก้ปัญหานี้ กลุ่มนักพัฒนา Gang of Four จึงได้นิยามรูปแบบเชิงพฤติกรรมที่เรียกว่า State Pattern ซึ่งช่วยให้ออบเจ็กต์สามารถปรับเปลี่ยนพฤติกรรมของตนเองได้เมื่อสถานะภายในเปลี่ยนแปลง โดยตัวออบเจ็กต์จะดูเสมือนว่าได้เปลี่ยนคลาสของตัวเองไป โครงสร้างนี้ประกอบด้วยสามส่วนสำคัญ และเริ่มต้นด้วยการกำหนดอินเทอร์เฟซ OrderStateInterface ซึ่งประกอบด้วยเมธอด pay, ship, cancel, refund และ getStatus

object oriented programming flowchart diagram

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ไม่อยากพลาดข่าวใหม่?

สมัครรับสรุปข่าวสารใหม่ทางอีเมล ไม่บ่อยจนรำคาญ

โฆษณา

สมมติว่ามีสถานะใหม่ถูกเพิ่มเข้ามา เช่น OnHoldState สำหรับคำสั่งซื้อที่ถูกระงับเพื่อรอการตรวจสอบการทุจริต นักพัฒนาเพียงแค่สร้างคลาสใหม่ขึ้นมาเพื่อ implement OrderStateInterface โดยระบุให้ชัดเจนว่าการดำเนินการใดบ้างที่ได้รับอนุญาตในสถานะนี้ พร้อมทั้งกำหนดการเปลี่ยนผ่านที่ถูกต้อง ซึ่งวิธีนี้จะทำให้ไม่มีสถานะอื่นใดต้องถูกแก้ไข และไม่มีเมธอดในคลาส Order ที่ต้องถูกปรับเปลี่ยน ส่งผลให้หลักการ Open/Closed Principle ถูกนำมาใช้งานได้อย่างเป็นธรรมชาติ

ในทางปฏิบัติ การเลือกใช้ State Pattern หรือแนวทางทางเลือกอย่าง Enum และ match ใน PHP 8.1+ นั้นขึ้นอยู่กับระดับความซับซ้อนของโปรเจกต์ แม้การใช้ Enum จะสะดวกในเคสขนาดเล็ก แต่หากระบบเติบโตขึ้น State Pattern จะช่วยแยกระเบียบวิธีและตรรกะของแต่ละสถานะออกจากกันอย่างเด็ดขาด ลดความเสี่ยงในการแก้ไขโค้ดเดิม และช่วยให้ทีมสามารถบำรุงรักษาซอฟต์แวร์ระยะยาวได้ดีขึ้น

นอกจากนี้ State Pattern ยังสามารถพัฒนาต่อยอดไปสู่ State Machine อย่างเป็นทางการได้ โดยมีการประกาศเงื่อนไขการเปลี่ยนผ่านที่ถูกต้องไว้อย่างชัดเจนในรูปแบบแมป เช่น การกำหนดให้สถานะ pending สามารถเปลี่ยนไปเป็น paid หรือ cancelled ได้เท่านั้น ซึ่งแนวทางนี้จะช่วยเพิ่มความปลอดภัยและรองรับการใช้งานผ่านไลบรารีเฉพาะทางในเฟรมเวิร์กต่างๆ เช่น Symfony Workflow และ Laravel State Machines

ที่มา: Dev.to

ความคิดเห็น

แสดงความคิดเห็น
0/2000

พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้