六、裝飾模式
阿新 • • 發佈:2018-11-22
一、基本概念
1、定義:動態地給一個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。 2、作用:為已有功能動態地新增更多功能的一種方式。 3、何時使用裝飾模式:當系統需要新功能時,要求向舊的類中新增新的程式碼,這些新的程式碼通常裝飾了原有類的核心職責或主要行為。 4、優點:把類中裝飾功能從類中搬移去除,這樣可以簡化原有的類。 有效地把類的核心職責和裝飾功能區分開了,而且可以去除相關類中重複的裝飾邏輯。 5、特點:在主類中加入了新的欄位,新的方法和新的邏輯,從而增加了主類的複雜度,並讓這個類包裝它所需要裝飾的物件,因此,當需要執行特殊行為時,客戶程式碼就可以在執行時根據需要有選擇地,按順序地
- 如果ConcreteComponent只有一個,沒有Component,就可以讓Decorator直接繼承ConcreteComponent;
- 如果ConcreteDecoratorA只有一種,就可以不要Decorator,直接讓ConcreteDecoratorA繼承Component。
二、示例:給小仙豬打扮一下
屬於簡化實施過程的第一種情況。1、UML圖
2、程式碼
Person類
1 package thirdDecoration; 2 3 // 相當於ConcreteCompement的person 4 public class Person { 5 private String name; 6 public Person(){} 7 public Person(String name){ 8 this.name=name; 9 } 10 11 public void show(){ //由於在Java中,普通類不能擁有抽象方法,且抽象方法無方法體,所以和書上C#的寫法不同 12 System.out.println("裝扮的"+this.name); 13 }; 14 }
服飾類
1 package thirdDecoration; 2 3 public class Finery extends Person { 4 protected Person compenent; 5 public void Decorate(Person person){ 6 this.compenent=person; 7 } 8 public void show(){ //通過覆寫的方式增加子類的特性 9 if (compenent!=null){ 10 compenent.show(); 11 } 12 } 13 }
具體服飾類
1 package thirdDecoration; 2 3 public class Tshirt extends Finery { 4 public void show(){ 5 System.out.println("T恤"); 6 super.show(); 7 } 8 }
1 package thirdDecoration; 2 3 public class Skirt extends Finery { 4 public void show(){ 5 System.out.println("超短裙"); 6 super.show(); 7 } 8 }
1 package thirdDecoration; 2 3 public class Dress extends Finery { 4 public void show(){ 5 System.out.println("連衣裙"); 6 super.show(); 7 } 8 }
客戶端
1 package thirdDecoration; 2 3 public class DecorationTest { 4 5 public static void main(String[] args) { 6 Person person=new Person("小仙豬");//把物件找出來 7 Tshirt tshirt=new Tshirt(); //把衣服準備好 8 Skirt skirt=new Skirt(); //把衣服準備好 9 10 skirt.Decorate(person);//裙子穿上 11 tshirt.Decorate(skirt);//再把上衣穿上 12 tshirt.show(); 13 14 System.out.println("done!"); 15 } 16 17 }
分析:
- 這部分和常理的理解有那麼一點不太一樣,因為我們正常是覺得,人還是那個人,但是穿了不同的衣服,人是主題,貫穿始終,但是這裡,人好像被包裹了一件衣服後,就不是這個人了。不過這只是一個例子而已。
- 裝飾功能的裝飾順序很重要,示例中“穿衣服”是比較隨性的,但是工程中,例如加密資料和過濾詞彙都可以是資料持久化的裝飾功能,但是一定是先過濾詞彙然後再加密,否則會出問題的。