The decorator design pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alernative to subclassing for extended functionality. The principle here is " Classes should be open for extension, but closed for modification." Other principles are: Encapsulate what varies. Favor composition over inheritance. Program to interfaces, not implementations. And, Strive for loosely coupled designs between objects that interact.
An example of the Decorator Design Pattern follows:
public abstract class Hamburger {
private String description = "Plain";
public abstract double getCost();
public String getDescription() { return description; }
}
public abstract class CondimentDecorator extends Hamburger {
// must re-implement this to call the decorated object
public abstract String getDescription();
}
// concrete class
// can also make AngusBurger, TurkeyBurger, SoyBurger, etc.
public class CheeseBurger extends Hamburger {
public CheeseBurger() { description = "CheeseBurger"; }
public double getCost() { return 5.99; }
}
// concrete class
// similar for mustard, pickles, relish, etc.
public class Ketchup extends CondimentDecorator {
Hamburger burger;
public Ketchup(Hamburger hamburger) { burger = hamburger; }
public String getDescription() {
retutn burger.getDescription() + ", with ketchup";
}
public double getCost() {
return burger.getCost() + 0.10;
}
}