Strategy pattern ช่วยเปลี่ยนอัลกอริทึมหลักภายในเมธอด โดยส่งผ่านคลาสที่ implement อัลกอริทึม แทนที่จะ hardcode ไว้ในคลาส "อัลกอริทึม" ที่นี่หมายถึงโค้ดลำดับขั้นตอนเพื่อผลลัพธ์ ไม่ใช่แค่ CS algorithms
When To Use The Strategy Pattern
แก้ปัญหา Open/Closed Principle: "Software entities ควร open สำหรับ extension แต่ closed สำหรับ modification" ไม่ควรแก้คลาสเพื่อเพิ่มฟีเจอร์ใหม่
ตัวอย่าง: ReportGenerator ต้องการหลาย format แทนที่จะเพิ่มเมธอดใหม่ทุกครั้ง (ละเมิด OCP) หรือ if/else ยาวๆ ให้อัลกอริทึมมาจาก ภายนอกคลาส แทน
Strategy Pattern Example
Strategy = คลาสที่มีเมธอดเดียว (เช่น format):
module ReportFormatters
class JSON
def self.format(data); data.to_json; end
end
class PlainText
def self.format(data); data.to_s; end
end
class HTML
def self.format(data)
html = "<ul>"
data.each { |product, amount| html << "<li>#{product}: #{amount}</li>" }
html << "</ul>"; html
end
end
end
ReportGenerator เรียกใช้:
class ReportGenerator
def self.generate(data, formatter)
formatter.format(data)
end
end
data = { onions: 31, potatoes: 24, eggs: 10 }
ReportGenerator.generate(data, ReportFormatters::HTML)
ReportGenerator.generate(data, ReportFormatters::JSON)
เปลี่ยน format แค่ส่ง strategy ตัวอื่น ต้อง implement format method เท่านั้น
Strategy pattern = จ้างที่ปรึกษาเฉพาะด้าน Decorator pattern = ตกแต่งต้นไม้คริสต์มาส
Summary
Strategy pattern ใช้เมื่อต้องการเปลี่ยนส่วนหนึ่งของคลาสโดยไม่แก้คลาสเอง ส่ง strategy เข้ามาแทน