装饰模式: Decorator Pattern
概括: 动态地给一个对象添加一些额外的职责。单从增加功能来说,用装饰模式比简单使用子类继承的方式来的灵活。
关键字: Has-a,
重点: 每个装饰类都要实现定义好的实现功能的纯虚装饰函数。各个装饰类都has-a一个拥有基本功能的类,通过对接口的实现,给has-a关系的基础功能增加新的功能
类图:
简单例子: http://en.wikipedia.org/wiki/Decorator_pattern
待装饰的基类:
// The Coffee Interface defines the functionality of Coffee implemented by decorator public interface Coffee { public double getCost(); // returns the cost of the coffee public String getIngredients(); // returns the ingredients of the coffee } // implementation of a simple coffee without any extra ingredients public class SimpleCoffee implements Coffee { public double getCost() { return 1; } public String getIngredients() { return "Coffee"; } }
----------------------虚装饰类:
// abstract decorator class - note that it implements Coffee interface abstract public class CoffeeDecorator implements Coffee { protected final Coffee decoratedCoffee; // has-a一个待装饰的基类 protected String ingredientSeparator = ", "; public CoffeeDecorator(Coffee decoratedCoffee) { this.decoratedCoffee = decoratedCoffee; } public double getCost() { // implementing methods of the interface return decoratedCoffee.getCost(); } public String getIngredients() { return decoratedCoffee.getIngredients(); } }
--------------------------------------------------------------------------------------
实际增加功能的装饰类,即提供给用户使用的装饰类:
// Decorator Milk that mixes milk with coffee // note it extends CoffeeDecorator public class Milk extends CoffeeDecorator { public Milk(Coffee decoratedCoffee) { super(decoratedCoffee); } public double getCost() { // overriding methods defined in the abstract superclass return super.getCost() + 0.5; } public String getIngredients() { return super.getIngredients() + ingredientSeparator + "Milk"; } }
--------------------------------------------------------------------------------------
实际用户子类:
public class Main { public static void main(String[] args) { Coffee c = new SimpleCoffee(); System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); c = new Milk(c); System.out.println("Cost: " + c.getCost() + "; Ingredients: " + c.getIngredients()); ... } }