Decorator
动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。该模式以对客户端透明的方式扩展对象的功能。
* 通过使用修饰模式,可以在运行时扩充一个类的功能。
* 原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。
* 装饰类实现新的功能,而在不需要用到新功能的地方,它可以直接调用原来的类中的方法。
* 修饰类必须和原来的类有相同的接口。
* 修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
* 当某个类具有多种可组合叠加的行为或属性时,装饰者模式可以通过动态增加装饰类,以避免排列组合,减少需要类的数量。
共同的接口或抽象类
1 public interface ITree { 2 void show(); 3 }
原本的类(未经过装饰)
public class Tree implements ITree { @Override public void show() { System.out.println("I am a tree."); } }
装饰类1
public class DecoratorApple implements ITree { private ITree tree; public DecoratorApple(ITree tree) { this.tree = tree; } public void show() { tree.show(); System.out.println("I have apple."); } }
装饰类2
public class DecoratorSnow implements ITree { private ITree tree; public DecoratorSnow(ITree tree) { this.tree = tree; } public void show() { tree.show(); System.out.println("I have snow."); } }
装饰类3
public class DecoratorFlower implements ITree { private ITree tree; public DecoratorFlower(ITree tree) { this.tree = tree; } public void show() { tree.show(); System.out.println("I have flower."); } }
使用
public class TestDecorator { public static void main(String[] args) { //普通的树 ITree tree = new Tree(); tree.show(); System.out.println("-----------------------"); // 装饰成一个苹果树 ITree appleTree = new DecoratorApple(tree); appleTree.show(); System.out.println("-----------------------"); // 装饰一个覆盖了雪的苹果树 ITree snowAppleTree = new DecoratorApple(new DecoratorSnow(new Tree())); snowAppleTree.show(); System.out.println("-----------------------"); // 装饰成一个开花的覆盖了雪的苹果树 ITree christmasTree = new DecoratorFlower(snowAppleTree); christmasTree.show(); } }
输出:
I am a tree. ----------------------- I am a tree. I have apple. ----------------------- I am a tree. I have snow. I have apple. ----------------------- I am a tree. I have snow. I have apple. I have flower.
end