定義
動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾模式生成子類更靈活。
使用場景
需要透明且動態的擴展類的功能時
關鍵點
一個抽象組件角色—接口或抽象類,被裝飾的原始對象
一個或多個具體組件—抽象組件的具體實現,被裝飾的具體對象
一個抽象裝飾角色—抽象類,裝飾組件對像,持有組件對象引用
一個或多個具體裝飾類—對抽象裝飾者的具體實現
實現
/**
* 抽象組件
*/
public abstract class AbsComponent {
/**
* 抽象方法,自由定義
*/
public abstract void doSomething();
}
/**
* 具體組件A
*/
public class ConcreteComponentA extends AbsComponent {
@Override
public void doSomething() {
//具體組件A的邏輯實現
}
}
/**
* 具體組件B
*/
public class ConcreteComponentB extends AbsComponent {
@Override
public void doSomething() {
//具體組件B的邏輯實現
}
}
/**
* 抽象裝飾—持有抽象組件(需要被裝飾的組件可以動態注入)
*/
public class AbsComponentWrapper extends AbsComponent {
private AbsComponent component;
public AbsComponentWrapper(AbsComponent component) {
this.component = component;
}
@Override
public void doSomething() {
component.doSomething();
}
}
/**
* 組件A的具體裝飾
*/
public class ComponentAWrapper extends AbsComponentWrapper {
public ComponentAWrapper(AbsComponent component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
doSomethingA();
}
/**
* 自定義一系列的裝飾方法
*/
public void doSomethingA() {
//裝飾A組件
}
}
/**
* 組件B的具體裝飾
*/
public class ComponentBWrapper extends AbsComponentWrapper {
public ComponentBWrapper(AbsComponent component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
doSomethingB();
}
/**
* 自定義一系列的裝飾方法
*/
public void doSomethingB() {
//裝飾B組件
}
}
小結
1.裝飾模式與繼承關係的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。
2.通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行爲的組合。
缺點
1.裝飾模式比繼承更加靈活機動的特性,同時意味着更加多的複雜性。
2.裝飾模式會導致設計中出現許多小類,如果過度使用,會使程序變得很複雜。
3.裝飾模式是針對抽象組件(Component)類型編程。但是,如果你=要針對具體組件編程時,就應該重新思考應用架構,以及裝飾者是否合適。當然也可以改變Component接口,增加新的公開的行爲,實現“半透明”的裝飾者模式。在實際項目中要做出最佳選擇。