1. แนวคิดของรูปแบบ Strategy

รูปแบบการทำงานเชิงพฤติกรรม (behavioral design pattern) หรือที่เรียกว่า "รูปแบบ Strategy" เป็นรูปแบบที่ช่วยให้เราสามารถเลือกใช้ขั้นตอนวิธีหรือพฤติกรรมต่าง ๆ ตามสถานการณ์ที่แตกต่างกันได้ โดยการห่อหุ้ม (encapsulate) ขั้นตอนวิธีต่าง ๆ ลงในคลาส Strategy แต่ละคลาสและอนุญาตให้คลาส Strategy เหล่านี้สามารถสลับกันได้ ด้วยการใช้รูปแบบ Strategy จะทำให้เราสามารถเปลี่ยนพฤติกรรมของอ็อบเจกต์ได้ในระหว่างรันไทม์โดยไม่ต้องแก้ไขโครงสร้างของอ็อบเจกต์โดยตรง

2. ลักษณะและข้อดีของรูปแบบ Strategy

รูปแบบ Strategy มีลักษณะและข้อดีดังนี้:

  • คลาส Strategy สามารถเปลี่ยนแปลงได้อิสระโดยการเพิ่มคลาส Strategy ใหม่โดยไม่ส่งผลต่อโค้ดเดิม สอดคล้องกับหลักการเปิด-ปิด (open-closed principle)
  • ลูกค้าสามารถเลือกใช้กลยุทธ์ที่แตกต่างกันตามความต้องการ สอดคล้องกับหลักการความรับผิดชอบเพียงคนเดียว (single responsibility principle)
  • รูปแบบ Strategy มุ่งไปที่การให้ใช้ซ้ำได้ของอัลกอริทึมหรือพฤติกรรม หลีกเลี่ยงการทำซ้ำโค้ด
  • รูปแบบ Strategy มุ่งไปที่การจัดระเบียบโค้ดที่ดีกว่า ทำให้โค้ดมีความชัดเจนและง่ายต่อการบำรุงรักษา

3. ตัวอย่างการประยุกต์ใช้รูปแบบ Strategy ในชีวิตจริง

รูปแบบ Strategy นั้นถูกนำไปใช้ในฐานะต่อไปนี้:

  • วิธีการชำระเงินที่แตกต่างกัน เช่น Alipay, WeChat Pay, ฯลฯ
  • อัลกอริทึมเรียงลำดับที่แตกต่างกัน เช่น การเรียงลำดับแบบ bubble sort, quicksort, ฯลฯ
  • วิธีการบันทึกข้อมูลที่แตกต่างกัน เช่น การแสดงผลบนคอนโซล, การบันทึกข้อมูลลงในไฟล์, ฯลฯ

4. การประยุกต์ใช้รูปแบบ Strategy ใน Golang

ในส่วนนี้ เราจะประยุกต์ใช้รูปแบบ Strategy ใน Golang และให้ตัวอย่าง ไดอะแกรมคลาส UML และความคิดเห็นเกี่ยวข้อง และคอมเมนต์โค้ด

4.1. ไดอะแกรมคลาส UML

ด้านล่างนี้คือไดอะแกรมคลาส UML สำหรับรูปแบบ Strategy ใน Golang:

Golang รูปแบบ Strategy

4.2. บทนำตัวอย่าง

จากไดอะแกรมคลาส UML ข้างต้น เราสามารถเห็นได้ว่ามีบทบาทสามอย่างของรูปแบบ Strategy: อินเทอร์เฟซ Strategy, คลาสกลยุทธ์ที่ให้เห็น (เช่น ConcreteStrategyA และ ConcreteStrategyB), และคลาสคอนเท็กซ์ Context

ในตัวอย่างนี้ เราจะใช้การเลือกวิธีการชำระเงินสำหรับคำสั่งของระบบอีคอมเมิร์ซ เพื่ออธิบาย ผู้ใช้เลือกกลยุทธ์ที่เกี่ยวข้อง (ConcreteStrategyA หรือ ConcreteStrategyB) ตามวิธีการชำระเงิน และจากนั้นเรียกเมธอดของคลาสคอนเท็กซ์เพื่อชำระเงิน

4.3. ขั้นตอนการสร้าง 1: กำหนดอินเทอร์เฟซกลยุทธ์และคลาสกลยุทธ์ที่ให้เห็น

ต้องกำหนดอินเทอร์เฟซกลยุทธ์ Strategy ที่รวมเมธอด Execute(data interface{}) string เพื่อทำการดำเนินกลยุทธ์เฉพาะ

type Strategy interface {
    Execute(data interface{}) string
}

type ConcreteStrategyA struct{}

func (s *ConcreteStrategyA) Execute(data interface{}) string {
    // ตรรกะสำหรับการดำเนินกลยุทธ์เฉพาะ A
}

type ConcreteStrategyB struct{}

func (s *ConcreteStrategyB) Execute(data interface{}) string {
    // ตรรกะสำหรับการดำเนินกลยุทธ์เฉพาะ B
}

4.4 ขั้นตอนการสร้าง 2: การสร้างคลาสคอนเท็กซ์

ต่อมา เราต้องการสร้างคลาสคอนเท็กซ์ Context ซึ่งห่อหุ้มวัตถุกลยุทธ์เฉพาะ และให้เมธอด SetStrategy(strategy Strategy) เพื่อกำหนดวัตถุกลยุทธ์ และเมธอด ExecuteStrategy(data interface{}) string เพื่อดำเนินกลยุทธ์เฉพาะ

type Context struct {
    strategy Strategy
}

func (c *Context) SetStrategy(strategy Strategy) {
    c.strategy = strategy
}

func (c *Context) ExecuteStrategy(data interface{}) string {
    if c.strategy == nil {
        // ตรรกะดำเนินการ์ายเริ่มต้นเรื่องกลยุทธ์
    } else {
        return c.strategy.Execute(data)
    }
}

4.5. ขั้นตอนการสร้าง 3: การใช้รูปแบบ Strategy เพื่อดำเนินการกิจกรรมทางธุรกิจจริง

ท้ายที่สุด เราสามารถนำรูปแบบ Strategy ไปใช้ในไคลเอ้นท์เพื่อดำเนินการงานทางธุรกิจจริง

func main() {
    context := &Context{}

    // กำหนดกลยุทธ์ที่เฉพาะ A โดยใช้เมธอด SetStrategy
    context.SetStrategy(&ConcreteStrategyA{})
    result := context.ExecuteStrategy("การชำระเงินด้วย Alipay")

    // กำหนดกลยุทธ์ที่เฉพาะ B โดยใช้เมธอด SetStrategy
    context.SetStrategy(&ConcreteStrategyB{})
    result = context.ExecuteStrategy("การชำระเงินด้วย WeChat Pay")
}

สรุป

ผ่านโค้ดตัวอย่างข้างต้น เราได้เรียนรู้การใช้รูปแบบ Strategy ใน Golang รูปแบบ Strategy ช่วยให้เราสามารถเลือกใช้ขั้นตอนวิธีหรือพฤติกรรมต่าง ๆ ตามสถานการณ์ที่แตกต่างกัน และมีที่วางโค้ดที่ดีกว่า ทำให้โค้ดมีความชัดเจนและง่ายต่อการบำรุงรักษา ในการพัฒนาจริง การใช้รูปแบบ Strategy อย่างมีเหตุผลสามารถทำให้ความสามารถในการขยายของรหัสและการบำรุงรักษาได้ถึงขีดสุด