模式定義
動態地給對象增加額外的職責
- 對象結構型模式
模式結構
- Component:抽象構件
- ConcreteComponent: 具體構件
- Decorator:抽象裝飾類
- ConcreteDecorator: 具體裝飾類
抽象裝飾類代碼
public class Decorator extends Component {private Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}}
具體裝飾類代碼
public class ConcreteDecorator extends Decorator {Object addedState; // 新增屬性public ConcreteDecorator(Component component) {super(component);}public void operation() {super.operation();addedBehavior();}// 新增方法public void addedBehavior() {// do something}}
- 一個裝飾類的接口必須與被裝飾類的接口保持相同
- 對于客戶端來說無論是裝飾之前的對象還是裝飾之后的對象都可以一致對待
- 盡量保持具體構件類Component作為一個“輕”類
- 不要把太多的邏輯和狀態放在具體構件類中可以通過裝飾類對其進行擴展
簡化裝飾模式
如果只有一個具體構件類而沒有抽象構件類,那么抽象裝飾類可以作為具體構件類的直接子類
透明裝飾模式
客戶端完全面向抽象編程
- 客戶端不聲明具體構件類型和具體裝飾類型,而全部聲明為抽象構件類型
半透明裝飾模式
客戶端面向抽象構件類型和具體裝飾類型編程
- 客戶端可以聲明具體裝飾者類型對象,調用具體裝飾者中新增方法
實例
某系統提供了一個數據加密功能,可以對字符串進行加密。最簡單的加密算法通過對字母進行移位來實現,同時還提供了稍復雜的逆向輸出加密,還提供了更為高級的求模加密。用戶先使用最簡單的加密算法對字符串進行加密,如果覺得還不夠可以對加密之后的結果使用其他加密算法進行二次加密,當然也可以進行第三次加密。現使用裝飾模式設計該多重加密系統。
模式分析
- 優點
- 提供比繼承更多的靈活性以擴展對象功能
- 通過配置文件在運行時選擇不同的裝飾器以動態擴展對象功能
- 具體構件類和具體裝飾類可以獨立變化
- 符合開閉原則
- 缺點
- 增加系統的復雜度
- 比繼承更加易于出錯,排錯困難
適用環境
- 在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責
- 需要動態地給一個對象增加功能,這些功能也可以動態地被撤銷
- 當不能采用繼承的方式對系統進行擴充或者采用繼承不利于系統擴展和維護時
- 系統中存在大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長
- 不能繼承的類定義(如final類)