熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Javascript >> 正文

講述在Java中Decorate的三種實現方法

2022-06-13   來源: Javascript 

  Decorator是用於裝飾一個事物(或人)的另一個事物(或人)一個Decorator直接改變被裝飾對象的職責或特征但是不能改變被裝飾對象的自有屬性
  
  從我們的專業角度來討論一些存在的實例
  
  JScrollPane可以裝飾JComponent的視圖部分JComponent本身並不會被改變但是增加了一個新的屬性(可滾動)
  
  BufferedInputStream是InputStream的裝飾子本身BufferedInputStream就是一個InputStream但是它更快因為提供了對數據的緩存
  
  考慮一下DebugButton它與JButton一樣但是它在被點擊時可以向日志文件添加消息DebugButton是JButton的裝飾子因為它直接改變了JButton但並沒有改變它的自有屬性
  
  再又如ScrollOverButton它增加了一個鼠標滑過的行為當鼠標移出時它是平的當鼠標經過時它具有一個凸起的邊框很顯然ScrollOverButton也是JButton的裝飾子現在我們知道Decorator可能有三種不同的實現
  
   繼承(Inheritance)
  
   封裝(Wrapper)
  
   外掛(External)
  
  本文將討論每一個實現模型以及它們的優缺點
  
  繼承
  
  對於開發人員而言最直觀的Decorator實現就是寫一個派生類它繼承自被裝飾類並賦於新的職責新的職責可以是通過增加方法或是修改已有方法來實現
  
  public class DebugButton extends JButton
  {
  public DebugButton()
  {
  addActionListener(new ActionListener()
  {
  Systemoutprintln(debug message);
  });
  }
  }
  
  此外我們也可以用相同的方式來實現ScrollOverButton不是增加ActionListener而是增加MouseListener在MouseListener回調方法中改變JButton的邊框當mouseEntered()被調用時將邊框從EmpetyBorder變為RaisedBevelBorder而當mouseExited()方法被調用時再將邊框從RaisedBevelBorder恢復成EmpetyBorder
  
  對於BufferedInputStream同樣實現也是非常簡單的修改每個讀數據的方法讓它從內存緩沖區來讀取數據如果緩沖區是空的它可以通過superread()方法來獲取數據並填充緩沖區JScrollPane要實現起來就有點復雜下面我將討論為什麼它會比較難以用繼承的方式來實現
  
  討論一下繼承方式實現Decorator模式的優點與缺點
  
  優點
  
   我們幾乎可以用這個方式實現所有的Decorator
  
   使用繼承方式實現Decorator模式可以保留被裝飾類的原始類型這一點是非常重要的用繼承方式我們仍可以使用被裝飾類的在被裝飾之前的類型例如我們可以在我們的應用程序中使用crollOverButton代替JButton但是JScrollPane就不能代替包含在它內部的對象
  
  缺點
  
   用繼承的方式仍不夠直接設想一下我們實現了ScrollOverButton和DebugButton但是我們又需要實現一個既有ScrollOverButton特點又有DebugButton行為的按鈕怎麼辦?用繼承方式我們唯一的選擇就是再派生出一個ScrollOverDebugButton類
  
  如果我們有了ScrollOverDebugButton的實現那麼是否還需要繼續保留ScrollOverButton或DebugButton實現?因為我們可以為ScrollOverDebugButton增加兩對方法來打開或關閉debug或scrollover的行為
  
  public void setDebug(boolean b);
  public boolean isDebug();
  
  public void setScrollOver(boolean b);
  public boolean isScrollOver();
  
  再進一步考慮如果將來我們有更多的裝飾功能增加新的UUUn個行為我們是不是要寫一個類叫UUUnButton?它是不是要包括n個這樣的方法
  
  public void setU(boolean b);
  public boolean getU;();
  
  每增加一個新的行為(Un+)給裝飾器就需要增加兩個新的方法並要修改這個裝飾器的代碼實現這明顯與面向對象的思想相悖可能會產生嚴重的後果(注意javaxswingJButton就是這樣實現的)
  
   多數可視化對象的行為是由風格參數來指定的而風格的改變是不可預知的當風格發生了改變我們不得不調整自己的改變正如上面所述使用繼承的方式可能需要改變實現的代碼
  
   要保證被裝飾類的原始類型也不是一件容易的事我們需要重載每個構造子有時甚至是靜態方式盡管這不困難但總是相當麻煩的一件事
  
  用繼承方式來實現Decorator模式並不象我們先前想像的那麼簡單許多時候我們並不知道將來我們需要哪一些裝飾器結果是使用繼承方式的Decorator在擴展性方面相當困難並且與面向對象的原則會產生沖突
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25290.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.