模式定義:
在不改變原有對象的基礎上,動態地給對象增加一些額外的職責/功能。
主要就是用來擴展類,對修改關閉,對擴展開放。
裝飾者模式必然有一個公共的接口或抽象類,用來作爲對象的傳遞
舉個栗子:
有一杯水,想加點奶,然後再加點珍珠,還想再加點冰塊。
Water接口類:
public interface Water {
public void addWater();
}
Water接口具體實現(被裝飾的對象):
public class Milk implements Water {
@Override
public void addWater() {
System.out.println("加水衝杯牛奶");
}
}
抽象裝飾類:
public abstract class Decorate implements Water{
private Water Water;
public Decorate(Water water) {
Water = water;
}
@Override
public void addWater() {
Water.addWater();
}
}
抽象裝飾類具體實現一:
public class DecorateBubbleTea extends Decorate {
public DecorateBubbleTea(Water water) {
super(water);
}
@Override
public void addWater() {
super.addWater();
addBubble();//新增功能
}
private void addBubble() {
System.out.println("奶茶加點珍珠");
}
}
抽象裝飾類具體實現二:
public class DecorateBubbleTeaIce extends Decorate {
public DecorateBubbleTeaIce(Water water) {
super(water);
}
@Override
public void addWater() {
super.addWater();
addIce();//新增功能
}
private void addIce() {
System.out.println("加點冰");
}
}
測試類:
public class Test {
public static void main(String[] args) {
new DecorateBubbleTeaIce(new DecorateBubbleTea(new Milk())).addWater();;//加奶加珍珠加冰
System.out.println("-------------------------------------------------------");
new DecorateBubbleTeaIce(new Milk()).addWater();//加奶加冰
System.out.println("-------------------------------------------------------");
new DecorateBubbleTea(new Milk()).addWater();//加奶加珍珠
}
// 加水衝杯牛奶
// 奶茶加點珍珠
// 加點冰
// -------------------------------------------------------
// 加水衝杯牛奶
// 加點冰
// -------------------------------------------------------
// 加水衝杯牛奶
// 奶茶加點珍珠
要點:
抽象裝飾類實現公共接口(Water),構造方法傳遞對象,對象調用接口方法。
所有的裝飾類都是繼承自公共的抽象裝飾,即對原有的Milk不修改,而能夠額外增加功能。
具體實現類重寫抽象裝飾類方法,保持父類方法,新增功能具體實現方法。
與類的繼承相比較:
類的繼承也能實現擴展行爲,但相比子類會繁多;比如要實現加奶要新增一個子類;實現加珍珠也新增一個子類,實現加奶加珍珠還要新增一個子類,加奶加珍珠加冰還要一個子類等等,子類就會相當繁多。
而採用裝飾者模式,功能的實現可以有多種組合實現,比如測試類的例子。