定義:
裝飾者是在不改變對象的情況下動態給對象添加屬性和行爲,將責任動態的附加在對象上。 與繼承有類似功能即擴展功能。
裝飾者模式與繼承的區別:
**繼承:**在子類擴展功能的時候是靜態的,並且是已知需要擴展的功能,是在編譯時實現的。
**裝飾者模式:**比繼承更靈活,可以動態的擴展功能,可以在編譯時實現。符合開閉原則:類對擴展開發,對修改關閉。 這也是裝飾者模式的優點。
缺點:
會出現很多的小類,難管理。
角色:
- 裝飾者和被裝飾者的父類:一個抽象的接口或抽象類,定義基本行爲。 裝飾者也繼承(實現)這個類不是爲了繼承固定的行爲,而是爲了讓裝飾者和被裝飾者屬於同一類型從而在裝飾的時候被裝飾者不會被修改。 也因此,裝飾類可以替換被裝飾類。
- 被裝飾者:具體被裝飾的對象
- 抽象裝飾者(Decorator):一個接口或抽象類,從外類裝飾被裝飾者,被裝飾者不需要知道裝飾者的存在。
- 具體裝飾者:繼承(實現)被裝飾者,定義需要附加在被裝飾者的責任,即擴展被裝飾者。
程序示例:
對於遊戲裝備的定價系統,一套遊戲裝備可能會附加武器、頭飾等其他的裝飾品一起售出,並且搭配不同的飾品售價不一,並且搭配的飾品是動態的。因此可以使用裝飾者模式,遊戲裝備是被裝飾者,武器、頭飾是裝飾者。
Java中的IO就是典型的裝飾者模式。
/**
* 被裝飾者和裝飾者的父類
*/
public abstract class GameComponent {
String desc = "遊戲裝備";
public String getDesc() {
return desc;
}
public abstract int getPrice();
}
/**
* 具體被裝飾者
*/
public class WangzheCon extends GameComponent {
@Override
public String getDesc() {
return "王者榮耀的裝備:";
}
@Override
public int getPrice() {
return 99;
}
}
/**
* 抽象裝飾者
*/
public abstract class MyDecorator {
public abstract String getDecs();
}
public class ClothDecora extends GameComponent {
GameComponent gameComponent;
public ClothDecora(GameComponent gameComponent) {
this.gameComponent = gameComponent;
}
@Override
public String getDesc() {
return "增加一種頭飾:";
}
@Override
public int getPrice() {
return 20+gameComponent.getPrice();
}
}
/**
* 具體裝飾者--武器裝飾者
* 繼承同一子類是爲了與被裝飾者關聯,保持被裝飾者的類型
*/
public class WeaponDecora extends GameComponent{
//需要持有被裝飾者
GameComponent gameComponent ;
public WeaponDecora(GameComponent gameComponent) {
this.gameComponent = gameComponent;
}
@Override
public String getDesc() {
return "添加一種武器:";
}
@Override
public int getPrice() {
return 30+gameComponent.getPrice();
}
}
測試類:
public static void main(String[] agrs){
WangzheCon wangzheCon= new WangzheCon();
System.out.println("描述:"+wangzheCon.getDesc()+wangzheCon.getPrice());
WeaponDecora weaponDecora = new WeaponDecora(wangzheCon);
System.out.println("武器裝飾描述:"+weaponDecora.getDesc()+weaponDecora.getPrice());
ClothDecora clothDecora = new ClothDecora(wangzheCon);
System.out.println("頭飾裝飾描述:"+clothDecora.getDesc()+clothDecora.getPrice());
//或者
WangzheCon wangzheCon1 = new WangzheCon();
WeaponDecora weaponDecora1 = new WeaponDecora(new ClothDecora(wangzheCon1));
System.out.println("裝備描述:"+weaponDecora1.getDesc()+weaponDecora1.getPrice());
}
代碼示例:https://github.com/MarinaTsang/demo/tree/master/decorator