[Design Pattern] Strategy Pattern in Depth

วันนี้ Blog นี้มาเน้นทางสาย Pattern กันเยอะ เชื่อว่าหลายๆคน Copy & Paste Development มาใช้งาน แต่ก็ไม่รู้ว่า มัน คือ อะไรครับ โดย Pattern ที่ผมมาเขียนลง Blog ในวันนี้ คือ Strategy Pattern ซึ่งข้อมูลส่วนใหญ่ผมเอามาจากของ Head First นะครับ ตัวอย่างมันอธิบายได้ง่ายดีครับ

ทำไมต้องใช้ Strategy

  • ทุกปัญหามันไม่สามารถแก้ไขด้วยกับใช้เทคนิคเดิมของ OOP – Inheritance ได้ไง ? ตัวอย่าง เช่น นายเจมส์ได้รับหน้าที่ในการสร้าง Class ของ Duck (เป็ด)  โดยที่เป็ดแต่ละชนิดมีพฤติกรรมที่แตกต่างกับครับ โดยที่เรา Design ไว้ให้ใช้มีพฤติกรรมที่ Class แม่ แล้วให้ Class ลูกสืบทอด(Inheritance) ไปใช้ครับ
  • ซึ่งพอมีชนิดของเป็ดที่หลากหลายขึ้น ดันเกิดข้อขัดแย้งต้องมา Override แก้ไขพฤติกรรมมันซะงั้น จริงๆ มันควรทำอย่างนั้นเหรอ (ลูกดื้อ เปลี่ยนพฤติกรรมของแม่)
  • ในเมื่อ Inheritance (IS-A) มันไม่ Work ต้องเปลี่ยนมาเป็นการประกอบร่าง composition (HAS-A)

เมื่อไหร่ควรจะใช้

  • เมื่อต้องการเพิ่ม Maintainability – เลือกประกอบสิ่งที่สนใจได้ ตอน Runtime เช่น MullarDuck ตอนอายุน้อยกว่า 14 วัน ยังบินไม่ไม่ได้นะ แต่ถ้ามากกว่านั้น เราสามารถ Set ความสามารถบิน (FlyWithWings) เพิ่มเข้าไปได้
  • งานชิ้นเดียวกัน แต่มีวิธีการคิด (Algorithm/Behavior) ที่หลากหลาย เช่น
    • การจ่ายค่าโดยสารรถเมล์ ซึ่งแต่ละรุ่นมีวิธีคิดที่แแตกต่างกัน
    • การเดินหมากรุก ซึ่งหมากแต่ละตัวตอนเดิน กับการถูกกิน มันมีกฏที่แตกต่างกันไป
  • Keyword
    • Interface – เป็นสัญญาว่า เรารู้จักกันนะ
    • Delegation – สั่งงาน ใครคนอื่นททำต่อ เช่น
      • เดิม – Duck จัดการวิธีการบินเองหมด
      • ใหม่ – เพิ่มความสามารถ จาก Class FlyWithWings แล้วสั่งให้ Class FlyWithWings ไปจัดการต่อ

Pattern มันเป็นอย่างไร – Class Diagram

  • Duck เป็นผู้สั่งการ แต่ไม่ได้สั่งผ่าน Class โดยตรงนะ แต่ Duck รู้จักกันผ่าน Interface ตามเส้นสีแดงใน Class Diagram เลย
  • จาก Class Diagram แต่ละชิ้นคล้ายเป็นส่วนประกอบ (composition) ขึ้นมาแทน

มุมมองตอน Runtime – Object Diagram

  • Mallard Duck
  • Rubber Duck

มุมมองลำดับการทำงาน – Sequence Diagram

  • สร้างผ่าน Constructor มาดู Code เทียบกับ Sequence Diagram ไปกันเลย

  • Client มา Set พฤติกรรมลงไปเอง มาลุยกันครับ

  • ตอนลองสั่งให้บิน โดยแสดงให้เห็นถึง Delegation ถ้าสาย Dev ดู Code ดีกว่าครับ