意圖:動態的將責任附加到對象上
什么時候使用:
1.在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責
2.處理那些可以撤銷的職責
3.當不能采用生成子類的方式進行擴充時
結構圖:
示例代碼:
1 package com.test.patten.decorator; 2 3 public interface Person { 4 void doCoding(); 5 }
1 package com.test.patten.decorator; 2 3 public class Employee implements Person { 4 5 @Override 6 public void doCoding() { 7 System.out.println("程序員加班寫程序啊,寫程序,終於寫完了。。。"); 8 } 9 10 }
1 package com.test.patten.decorator; 2 3 public abstract class Manager implements Person{ 4 5 //裝飾器增加功能 6 public abstract void doCoding(); 7 8 }
1 package com.test.patten.decorator; 2 3 public class ManagerA extends Manager { 4 private Person person;//給雇員升職 5 6 public ManagerA(Person person) { 7 super(); 8 this.person = person; 9 } 10 @Override 11 public void doCoding() { 12 doEarlyWork(); 13 person.doCoding(); 14 } 15 /** 16 * 項目經理開始前期准備工作 17 */ 18 public void doEarlyWork() { 19 System.out.println("項目經理A做需求分析"); 20 System.out.println("項目經理A做架構設計"); 21 System.out.println("項目經理A做詳細設計"); 22 } 23 }
1 package com.test.patten.decorator; 2 3 public class ManagerB extends Manager { 4 private Person person;//給雇員升職 5 6 public ManagerB(Person person) { 7 super(); 8 this.person = person; 9 } 10 @Override 11 public void doCoding() { 12 person.doCoding(); 13 doEndWork(); 14 } 15 /** 16 * 項目經理開始項目收尾工作 17 */ 18 public void doEndWork() { 19 System.out.println("項目經理B 在做收尾工作"); 20 } 21 22 }
測試一下:
1 package com.test.patten.decorator; 2 3 public class Client { 4 public static void main(String args[]){ 5 Person employee = new Employee(); 6 employee = new ManagerA(employee);//賦予程序猿項目經理A職責 7 employee = new ManagerB(employee);//賦予程序猿項目經理B職責 8 9 employee.doCoding(); 10 } 11 }
項目經理A做需求分析 項目經理A做架構設計 項目經理A做詳細設計 程序員加班寫程序啊,寫程序,終於寫完了。。。 項目經理B 在做收尾工作
實際應用中的例子:java i/o
應用到的設計原則:對擴展開放,對修改關閉
優缺點:
1.裝飾者類反應出被裝飾的組件類型
2.裝飾者類可以在被裝飾者的行為前面或后面加上自己的行為,甚至取代被裝飾者的行為,達到特定的目的
3.可以用無數個裝飾者包裝一個組件,裝飾者類會導致設計中出現許多小對象,過度使用會讓程序變的復雜
4.裝飾者一般對組件的客戶是透明的,除非客戶程序依賴於組件的具體類型