รูปแบบ decorator เป็นรูปแบบในกลุ่ม behavioural design pattern รูปแบบ decorator เป็นรูปแบบที่ช่วยให้เราสามารถเพิ่มพฤติกรรมของออบเจกต์ในขณะใช้งานได้ตามต้องการโดยไม่กระทบกับออบเจกต์อื่นที่มาจากคลาสเดียวกัน และไม่ต้องไปเพิ่มพฤติกรรมในทุกๆออบเจกต์ โดยออบเจกต์ที่เป็น decorator หรือเรียกว่าเป็นพฤติกรรมที่ต้องการจะเพิ่ม จะหุ้ม (wrap) ออบเจกต์ที่ต้องการเปลี่ยนแปลงพฤติกรรมและเพิ่มฟังก์ชั่นให้กับออบเจกต์ที่ถูกหุ้มโดยการมอบหมายให้ออบเจกต์ที่ถูกหุ้มเป็นคนเรียกใช้เมธอดที่เพิ่มมาใหม่ ทำให้สามารถเพิ่ม แก้ไข หรือยกเลิกพฤติกรรมของออบเจกต์ที่ถูกหุ้มได้
รูปแบบ decorator จะเป็นไปตามหลักการ open/closed principle คือสามารถเพิ่มขยายความสามารถของโปรแกรมได้โดยไม่ต้องแก้ไขรหัสโปรแกรมเดิม รูปแบบ decorator มักจะถูกใช้ในเฟรมเวิร์คของการติดต่อผู้ใช้งานแบบกราฟฟิก (GUI) เช่น การแต่งวิดเจตด้วยขอบ แถบเลื่อน และส่วนประกอบแบบภาพทัศน์ (visual) อื่นๆ และถูกใช้กับเว็บในการเพิ่มความสามารถของวัตถุในขณะใช้งานโดยไม่ต้องแก้ไขรหัสโปรแกรม
ตัวอย่างด้านล่างเป็นการใช้รูปแบบ decorator ในภาษาจาวา โดยเริ่มจากสร้างคลาสแบบอินเตอร์เฟส Pizza เพื่อเป็นภาพสรุปของพิซซ่าพื้นฐาน
public interface Pizza {
public String getDescription();
public double getCost();
}
จากนั้นจึงสร้างคลาส PlainPizza ซึ่งเป็นคลาสที่ระบุลักษณะของพิซซ่าจริงๆซึ่งขยายมาจากคลาสแบบอินเตอร์เฟส Pizza
public class PlainPizza implements Pizza {
public String getDescription() {
return “Thin dough”;
}
public double getCost() {
return 4.00;
}
}
จากนั้นจึงสร้างคลาสแบบแอบแสตรก PizzaDecorator ซึ่งขยายมาจากคลาสแบบอินเตอร์เฟส Pizza คลาสนี้จะเป็นภาพสรุปของคลาสที่จะมาเป็น decorator
public abstract class PizzaDecorator implements Pizza {
protected Pizza pizza;
public PizzaDecorator(Pizza pizza) {
this.pizza = pizza;
}
public String getDescription() {
return pizza.getDescription();
}
public double getCost() {
return pizza.getCost();
}
}
จากนั้นจึงสร้างคลาสที่ระบุลักษณะของ decorator ซึ่งขยายมาจากคลาสแบบแอบแสตรก PizzaDecorator
public class Cheese extends PizzaDecorator {
public Cheese(Pizza pizza) {
super(pizza);
}
public String getDescription() {
return pizza.getDescription() + “, mozzarella cheese”;
}
public double getCost() {
return pizza.getCost() + 0.50;
}
}
public class TomatoSauce extends PizzaDecorator {
public TomatoSauce(Pizza pizza) {
super(pizza);
}
public String getDescription() {
return pizza.getDescription() + “, tomato sauce”;
}
public double getCost() {
return pizza.getCost() + 0.25;
}
}
ในการใช้งานเราจะหุ้มออบเจกต์พิซซ่าด้วยออบเจกต์ของ decorator ซึ่งเราสามารถหุ้มได้มากกว่า 1 ชั้นซึ่งเป็นการเพิ่มมากกว่า 1 พฤติกรรม
public class DecoratorExample {
public static void main(String[] args) {
Pizza pizza = new TomatoSauce(new Cheese(new PlainPizza()));
System.out.println(“Ingredients: ” + pizza.getDescription());
System.out.println(“Cost: ” + pizza.getCost());
}
}
output :
Ingredients: Thin dough, mozzarella cheese, tomato sauce
Cost: 4.75