(java)從零開始之--裝飾者設計模式

裝飾者設計模式
簡單定義:加強一個類的功能,並且還可讓這些裝飾類互相裝飾。設計模式

應用場景:當要在某個功能的基礎上擴充功能,而且擴充的功能具備大量排列組合,經過繼承關係會衍生出大量子類,這時候用裝飾者模式來解決。ide

裝飾者設計模式的步驟
1. 在裝飾類的內部維護一個被裝飾類的引用。
2. 讓裝飾類有一個共同的父類或者是父接口。ui

例如:人有一種行爲叫「吃水果」,其中水果有4種:蘋果、香蕉、鴨梨、橘子
如今有需求以下:
A類人行爲:吃蘋果
B類人行爲:先吃蘋果,再吃香蕉
C類人行爲:先吃香蕉,再吃蘋果
D類人行爲:先吃橘子,後吃鴨梨this

咱們先用子類繼承來實現:代碼以下spa

 1 interface IEatFruit{
 2 public void eatFruit();
 3 }
 4 
 5 class PersonA implements IEatFruit{
 6 
 7   @Override
 8   public void eatFruit() {
 9     System.out.println("吃蘋果"); 
10   }
11 
12 }
13 class PersonB implements IEatFruit{
14 
15 @Override
16   public void eatFruit() {
17     System.out.println("吃蘋果"); 
18     System.out.println("吃香蕉"); 
19   }
20 
21 }
22 class PersonC implements IEatFruit{
23 
24   @Override
25   public void eatFruit() {
26     System.out.println("吃香蕉");
27     System.out.println("吃蘋果"); 
28   }
29 
30 }
31 class PersonD implements IEatFruit{
32 
33   @Override
34   public void eatFruit() {
35     System.out.println("吃橘子");
36     System.out.println("吃鴨梨"); 
37   }
38 
39 }

 

這樣固然是沒問題的,每一類人對應new出來的對象 均可以實現對應的需求。
可是,當需求改成:
某類人行爲:吃上面四種水果,而且要求有前後順序
這樣的排列組合有24種....
這樣你還會用繼承去作嗎?寫24個子類去實現接口,明顯不合適。
這時候若是用到裝飾者模式,代碼則會變成:設計

  1 interface IEatFruit{
  2     public void eatFruit();
  3 }
  4 
  5 class PersonA implements IEatFruit{
  6     IEatFruit eat;
  7     public PersonA(){
  8         this.eat = this;
  9     }
 10     public PersonA(IEatFruit _eat){
 11         this.eat = _eat;
 12     }
 13     @Override
 14     public void eatFruit() {
 15         if(!(this.eat instanceof PersonA)){
 16             this.eat.eatFruit();
 17             System.out.println("吃蘋果"); 
 18         }else{
 19             System.out.println("吃蘋果"); 
 20         }
 21     }
 22     
 23 }
 24 class PersonB implements IEatFruit{
 25     IEatFruit eat;
 26     public PersonB(){
 27         this.eat = this;
 28     }
 29     public PersonB(IEatFruit _eat){
 30         this.eat = _eat;
 31     }
 32     @Override
 33     public void eatFruit() {
 34         if(!(this.eat instanceof PersonB)){
 35             this.eat.eatFruit();
 36             System.out.println("吃香蕉"); 
 37         }else{
 38             System.out.println("吃香蕉"); 
 39         }
 40     }
 41     
 42 }
 43 class PersonC implements IEatFruit{
 44     IEatFruit eat;
 45     public PersonC(){
 46         this.eat = this;
 47     }
 48     public PersonC(IEatFruit _eat){
 49         this.eat = _eat;
 50     }
 51     @Override
 52     public void eatFruit() {
 53         if(!(this.eat instanceof PersonC)){
 54             this.eat.eatFruit();
 55             System.out.println("吃鴨梨"); 
 56         }else{
 57             System.out.println("吃鴨梨"); 
 58         }
 59     }
 60     
 61 }
 62 class PersonD implements IEatFruit{
 63     IEatFruit eat;
 64     public PersonD(){
 65         this.eat = this;
 66     }
 67     public PersonD(IEatFruit _eat){
 68         this.eat = _eat;
 69     }
 70     @Override
 71     public void eatFruit() {
 72         if(!(this.eat instanceof PersonD)){
 73             this.eat.eatFruit();
 74             System.out.println("吃橘子"); 
 75         }else{
 76             System.out.println("吃橘子"); 
 77         }
 78     }
 79     
 80 }
 81 
 82 
 83 
 84 public class Demo2 {
 85 
 86     public static void main(String[] args) {
 87         //這樣就能夠經過上述4類人來相互裝飾,就能夠隨意任意一種組合「吃水果」
 88         //如:吃橘子->吃蘋果
 89         PersonD d = new PersonD();
 90         PersonA a = new PersonA(d);
 91         a.eatFruit();
 92         System.out.println("-------我是分割線------------");
 93         //如:吃蘋果->吃橘子->吃鴨梨->吃香蕉
 94         PersonA a2 = new PersonA();
 95         PersonD d2 = new PersonD(a2);
 96         PersonC c2 = new PersonC(d2);
 97         PersonB b2 = new PersonB(c2);
 98         b2.eatFruit();
 99     }
100 
101 }

輸出結果以下:
吃橘子
吃蘋果
-------我是分割線------------
吃蘋果
吃橘子
吃鴨梨
吃香蕉code

最後總結
繼承實現的加強類和修飾模式實現的加強類有何區別?
繼承實現的加強類:
優勢:代碼結構清晰,並且實現簡單.
缺點:對於每個的須要加強的類都要建立具體的子類來幫助其加強,這樣會致使
繼承體系過於龐大。
裝飾者模式實現的加強類:
優勢:內部能夠經過多態技術對多個須要加強的類進行加強, 可使這些裝飾類
達到互相裝飾的效果。使用比較靈活。
缺點:須要內部經過多態維護須要被加強的類的實例。進而使得代碼稍微複雜對象

相關文章
相關標籤/搜索