装饰模式:动态地给给对象增加一些额外的职责
从图中看到,具体组件和装饰都是抽象组件的子类,因此,抽象组件声明的对象既可以存放被装饰者的引用,也可以存放装饰者的引用。装饰模式最想达到的效果是,如果不加装饰,那就是原始组件的样子,如果想增加不同的属性,就通过装饰类,并且如果增加多个不同的属性,那最好通过多次调用装饰类来达到效果,可以通过合理设置装饰类的构造方法参数来实现。
使用装饰模式相对于继承机制的优势是:如果现在又需要一个新的子类,需要飞的更远的一种鸟,如果采用继承的方式那必须增加一个新的子类,如果采用上面的方式,则是增加一个新的装饰,即在原来装饰的基础上继续装饰,将对象再次传入装饰类中。
下面的实例中,普通的鸟能飞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());
}
}