介紹
裝飾器模式(Decorator Pattern)允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結構。
繼承機制同樣可以給現(xiàn)有類增加功能,通過繼承一個現(xiàn)有類可以使得子類在擁有自身方法的同時還擁有父類的方法。但是這種方法是靜態(tài)的,用戶不能控制增加行為的方式和時機。
而裝飾器模式是將一個類的對象嵌入另一個對象中,由另一個對象來決定是否調(diào)用嵌入對象的行為以便擴展自己的行為。
結構圖
這里寫圖片描述
時序圖
這里寫圖片描述
案例
我這邊就用街邊小吃來舉例子??腿丝梢赃x擇面條、米粉等,然后可以在面條或者米粉上添加其他一些小吃,如火腿、丸子等等。
食物接口
public interface Food {
void getDescription();
int getMoney();
}
面條主食
public class NoodleFood implements Food{
@Override
public void getDescription() {
System.out.print("-面條-");
}
@Override
public int getMoney() {
return 4;
}
}
米粉主食
public class FlourFood implements Food{
@Override
public void getDescription() {
System.out.print("-米粉-");
}
@Override
public int getMoney() {
return 5;
}
}
裝飾接口
public interface CondimentDecorator extends Food{
}
丸子裝飾類
public class BallDecorator implements CondimentDecorator{
private Food food;
public BallDecorator(Food food) {
this.food = food;
}
@Override
public void getDescription() {
food.getDescription();
System.out.print("-丸子-");
}
@Override
public int getMoney() {
return food.getMoney()+3;
}
}
火腿裝飾類
public class HamDecorator implements CondimentDecorator{
private Food food;
public HamDecorator(Food food) {
this.food = food;
}
@Override
public void getDescription() {
food.getDescription();
System.out.print("-火腿-");
}
@Override
public int getMoney() {
return food.getMoney()+3;
}
}
測試類
public class Client {
public static void main(String[] args) {
Food food = new HamDecorator(new BallDecorator(new HamDecorator(new NoodleFood())));
food.getDescription();
System.out.println();
System.out.println(food.getMoney());
Food food2 = new BallDecorator(new HamDecorator(new BallDecorator(new FlourFood())));
food2.getDescription();
System.out.println();
System.out.println(food2.getMoney());
}
}
測試結果
這里寫圖片描述
總結
使用裝飾模式來實現(xiàn)擴展比繼承更加靈活,它以對客戶透明的方式動態(tài)地給一個對象附加更多的責任。如果使用繼承會照成類爆炸。而且繼承是一種耦合度較大的靜態(tài)關系,無法在程序運行時動態(tài)擴展。
裝飾模式包含四個角色:抽象構件定義了對象的接口,可以給這些對 象動態(tài)增加職責(方法);具體構件定義了具體的構件對象,實現(xiàn)了 在抽象構件中聲明的方法,裝飾器可以給它增加額外的職責(方法); 抽象裝飾類是抽象構件類的子類,用于給具體構件增加職責,但是具 體職責在其子類中實現(xiàn);具體裝飾類是抽象裝飾類的子類,負責向構 件添加新的職責。
在jdk中最典型的就是I/O了,感興趣的可以去了解io的源碼。
這里寫圖片描述
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("1.txt")));