Decorator pattern ช่วย เพิ่มความสามารถใหม่ให้อ็อบเจ็กต์ โดยไม่ต้องเปลี่ยนคลาส
Logging & Performance
ใช้ rest-client ทำ HTTP request ต้องการเพิ่ม logging แต่ไม่แก้ RestClient module:
module LogHTTPRequest
def get(url)
puts "Sending Request For #{url}"
super
end
end
ใช้ extend เพิ่ม logging ให้อ็อบเจ็กต์เดียว:
class HTTPClient
def initialize(client = RestClient); @client = client; end
def get(*args); @client.get(*args); end
end
client = HTTPClient.new
client.extend(LogHTTPRequest)
client.get("rubyguides.com")
ต้องสร้าง wrapper class เพราะ RestClient เป็น module
When To Use The Decorator Pattern
ข้อดี: enhance เพียงอ็อบเจ็กต์เดียว ได้ มี client ที่ log และไม่ log พร้อมกัน Layer decorators ได้ (logging, performance testing) ไม่ทำได้ด้วย inheritance (ต้องสร้าง class HTTPClientWithLoggingAndPerformanceTesting)
Decorator pattern แก้ปัญหานี้ พร้อมหลีกเลี่ยง code duplication และชื่อคลาสแปลกๆ
Summary
Decorator pattern เพิ่มความสามารถให้อ็อบเจ็กต์โดยไม่แก้คลาส ลองฝึกปฏิบัติเองเพื่อจดจำเมื่อต้องใช้จริง!