装饰模式:动态地给给对象增加一些额外的职责
从图中看到,具体组件和装饰都是抽象组件的子类,因此,抽象组件声明的对象既可以存放被装饰者的引用,也可以存放装饰者的引用。装饰模式最想达到的效果是,如果不加装饰,那就是原始组件的样子,如果想增加不同的属性,就通过装饰类,并且如果增加多个不同的属性,那最好通过多次调用装饰类来达到效果,可以通过合理设置装饰类的构造方法参数来实现。
使用装饰模式相对于继承机制的优势是:如果现在又需要一个新的子类,需要飞的更远的一种鸟,如果采用继承的方式那必须增加一个新的子类,如果采用上面的方式,则是增加一个新的装饰,即在原来装饰的基础上继续装饰,将对象再次传入装饰类中。
下面的实例中,普通的鸟能飞100米,一个额外的翅膀加上去可以飞50米,那如果装饰中加了一个翅膀,那就能多飞50米。
package dai; public abstract class Bird { //表示能飞多远 public abstract int fly(); }
package dai; /** * @author Roger * 具体组件 */ public class Sparrow extends Bird{ @Override public int fly() { // TODO Auto-generated method stub return 100; } }
package dai; public class Decorator extends Bird{ @Override public int fly() { // TODO Auto-generated method stub return 100; } }
package dai; public class SparrowDecorator extends Decorator{ Bird sparrow; public SparrowDecorator(Bird sparrow) { super(sparrow); this.sparrow = sparrow; } @Override public int fly() { // TODO Auto-generated method stub return this.sparrow.fly()+eleFLY(); //在装饰类中加上了新的特性 } private int eleFLY(){ return 50; } }
package dai; public class Client { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //未添加装饰 Bird sparrow = new Sparrow(); System.out.println(sparrow.fly()); //一类装饰是一个类,如果需要添加装饰,只要将需要添加装饰的对象传入,传入的对象已经加过装饰 //添加了装饰 Bird sparrowDecorator = new SparrowDecorator(sparrow); System.out.println(sparrowDecorator.fly()); //继续添加装饰 Bird sparrowDecorator2 = new SparrowDecorator(sparrowDecorator); System.out.println(sparrowDecorator2.fly()); } }