裝飾設計模式,顧名思義,就是對一個功能進行裝飾,就跟女人化妝一樣,人還是本人,但是化了妝就變得比原來更漂亮了。
需求:當你有個功能是在N年前建立的,如今老大覺得功能不夠用了,需要進行增強,那麼怎麼辦呢?
解決:你就可以定義類,將已有對象傳入,基於已有的功能,並提供加強功能。如果這個功能寫錯了,又可以把自己寫的功能去掉而不影響以前的功能,是不是很靈活啊。這個類就是裝飾類。
裝飾設計模式呢,主要是對一組類進行功能的增強。
那麼什麼時候會用到裝飾模式呢?
1.需要擴展一個類的功能,或給一個類增加附加責任
2.需要動態的給一個對象增加功能,這些功能可以再動態的撤銷
3.需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變得不現實
好了,上菜了。
(由於本人比較笨,想不出什麼比較恰當的例子,這裏就借鑑一下http://blog.csdn.net/furongkang/article/details/7214100中的例子。什麼?你說我懶? 哼,好吧,我承認我懶。)
1 /* 2 3 我家裏有兩套房子:平房,樓房。 4 5 House 6 |--PingFang 7 |--LouFang 8 9 可是像我這麼土豪,又具有強烈的文藝範,又有衆多妻妾。。。 相信你已經感覺到了我的霸王之氣。 10 所以: 11 1,對平房進行田園風光式的打造。 12 2,對樓房進行歐式風格的打造。 13 可以通過繼承的方式來完成。 14 15 House 16 |--PingFang 17 |--TianYuanPingFang 18 |--LouFang 19 |--OuShiLouFang 20 21 */ 22 abstract class House { 23 abstract void show(); 24 } 25 26 class PingFang extends House { 27 public void show() { 28 System.out.println("平房"); 29 } 30 } 31 32 class TianYuanPingFang extends PingFang { 33 public void showTianYuan() { 34 super.show(); 35 System.out.println("田園風格"); 36 } 37 } 38 39 class LouFang extends House { 40 public void show() { 41 System.out.println("樓房"); 42 } 43 } 44 45 class OuShiLouFang extends LouFang { 46 public void showOuShi() { 47 super.show(); 48 System.out.println("歐式風格"); 49 } 50 } 51 52 class HouseDemo { 53 public static void main(String[] args) { 54 PingFang p = new PingFang(); 55 // p.show(); 56 57 TianYuanPingFang t = new TianYuanPingFang(); 58 t.showTianYuan(); 59 60 LouFang l = new LouFang(); 61 // l.show(); 62 OuShiLouFang o = new OuShiLouFang(); 63 o.showOuShi(); 64 } 65 }
上面的代碼實現了我需要的功能,但是如果單單爲了某個功能而去繼承,那麼那個體系是非常臃腫的。你說感覺不出來?假如你有幾百個類,那麼就會需要再寫上幾百個子類去繼承。能累死個人。
裝飾模式比繼承要靈活。避免了繼承體系臃腫。而且降低了類於類之間的關係。裝飾類因爲增強已有對象,具備的功能和已有的是相同的,只不過提供了更強功能。所以裝飾類和被裝飾類通常是都屬於一個體系中的。
裝飾類通常會通過構造方法接收被裝飾的對象。並基於被裝飾的對象的功能,提供更強的功能。
使用裝飾設計模式進行裝飾:
1 /* 2 原體系: 3 House 4 |--PingFang 5 |--LouFang 6 7 通過繼承之後的體系 8 House 9 |--PingFang 10 |--TianYuanPingFang 11 |--LouFang 12 |--OuShiLouFang 13 14 無論將平房打造成田園還是歐式,都是對平房一種裝修。 15 而該裝修也可以用樓房。 16 17 將現將該裝修定義好,需要把什麼房子進行改裝修,傳入即可。 18 House 19 |--PingFang 20 |--LouFang 21 |--TianYuan 22 |--OuShi 23 24 */ 25 abstract class House { 26 abstract void show(); 27 } 28 29 class PingFang extends House { 30 public void show() { 31 System.out.println("平房"); 32 } 33 } 34 35 class LouFang extends House { 36 public void show() { 37 System.out.println("樓房"); 38 } 39 } 40 41 class TianYuan extends House { 42 43 private House h; 44 45 TianYuan(House h) { 46 this.h = h; 47 } 48 49 public void show() { 50 System.out.println("田園風格"); 51 } 52 53 public void showTianYuan() { 54 h.show(); 55 this.show(); 56 } 57 58 } 59 60 class OuShi extends House { 61 private House h; 62 63 OuShi(House h) { 64 this.h = h; 65 } 66 67 public void show() { 68 System.out.println("歐式風格"); 69 } 70 71 public void showOuShi() { 72 h.show(); 73 this.show(); 74 } 75 76 } 77 78 class HouseDemo2 { 79 public static void main(String[] args) { 80 PingFang p = new PingFang(); 81 LouFang l = new LouFang(); 82 83 OuShi o = new OuShi(new TianYuan(p)); 84 o.showOuShi(); 85 86 // TianYuan t = new TianYuan(l); 87 // t.showTianYuan(); 88 89 // OuShi o = new OuShi(l); 90 // o.showOuShi(); 91 } 92 }
是不是好了很多呢。