裝飾模式:動態地給給對象增加一些額外的職責
從圖中看到,具體組件和裝飾都是抽象組件的子類,因此,抽象組件聲明的對象既可以存放被裝飾者的引用,也可以存放裝飾者的引用。裝飾模式最想達到的效果是,如果不加裝飾,那就是原始組件的樣子,如果想增加不同的屬性,就通過裝飾類,並且如果增加多個不同的屬性,那最好通過多次調用裝飾類來達到效果,可以通過合理設置裝飾類的構造方法參數來實現。
使用裝飾模式相對於繼承機制的優勢是:如果現在又需要一個新的子類,需要飛的更遠的一種鳥,如果採用繼承的方式那必須增加一個新的子類,如果採用上面的方式,則是增加一個新的裝飾,即在原來裝飾的基礎上繼續裝飾,將對象再次傳入裝飾類中。
下面的實例中,普通的鳥能飛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());
}
}