国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

講述在Java中Decorate的三種實(shí)現(xiàn)方法

2019-11-18 10:49:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  Decorator是用于裝飾一個(gè)事物(或人)的另一個(gè)事物(或人)。一個(gè)Decorator直接改變被裝飾對(duì)象的職責(zé)或特征,但是不能改變被裝飾對(duì)象的自有屬性。
  
  從我們的專(zhuān)業(yè)角度來(lái)討論一些存在的實(shí)例:
  
  1、JScrollPane可以裝飾JComponent的視圖部分。JComponent本身并不會(huì)被改變,但是增加了一個(gè)新的屬性(可滾動(dòng))。
  
  2、BufferedInputStream是InputStream的裝飾子,本身BufferedInputStream就是一個(gè)InputStream,但是它更快,因?yàn)樘峁┝藢?duì)數(shù)據(jù)的緩存。
  
  3、考慮一下DebugButton,它與JButton一樣,但是它在被點(diǎn)擊時(shí)可以向日志文件添加消息。DebugButton是JButton的裝飾子,因?yàn)樗苯痈淖兞薐Button但并沒(méi)有改變它的自有屬性。
  
  4、再又如ScrollOverButton,它增加了一個(gè)鼠標(biāo)滑過(guò)的行為。當(dāng)鼠標(biāo)移出時(shí)它是平的,當(dāng)鼠標(biāo)經(jīng)過(guò)時(shí)它具有一個(gè)凸起的邊框。很顯然,ScrollOverButton也是JButton的裝飾子。現(xiàn)在,我們知道Decorator可能有三種不同的實(shí)現(xiàn):
  
  1 繼續(xù)(Inheritance)
  
  2 封裝(Wrapper)
  
  3 外掛(External)
  
  本文將討論每一個(gè)實(shí)現(xiàn)模型,以及它們的優(yōu)缺點(diǎn)。
  
  繼續(xù)
  
  對(duì)于開(kāi)發(fā)人員而言,最直觀(guān)的Decorator實(shí)現(xiàn)就是:寫(xiě)一個(gè)派生類(lèi),它繼續(xù)自被裝飾類(lèi),并賦于新的職責(zé)。新的職責(zé)可以是通過(guò)增加方法或是修改已有方法來(lái)實(shí)現(xiàn)。
  
  public class DebugButton extends JButton
  {
  public DebugButton()
  {
  addActionListener(new ActionListener()
  {
  System.out.  });
  }
  }
  
  此外,我們也可以用相同的方式來(lái)實(shí)現(xiàn)ScrollOverButton:不是增加ActionListener,而是增加MouseListener。在MouseListener回調(diào)方法中改變JButton的邊框,當(dāng)mouseEntered()被調(diào)用時(shí),將邊框從EmpetyBorder變?yōu)镽aisedBevelBorder。而當(dāng)mouseExited()方法被調(diào)用時(shí),再將邊框從RaisedBevelBorder恢復(fù)成EmpetyBorder。
  
  對(duì)于BufferedInputStream,同樣實(shí)現(xiàn)也是非常簡(jiǎn)單的。修改每個(gè)讀數(shù)據(jù)的方法,讓它從內(nèi)存緩沖區(qū)來(lái)讀取數(shù)據(jù)。假如緩沖區(qū)是空的,它可以通過(guò)super.read()方法來(lái)獲取數(shù)據(jù)并填充緩沖區(qū)。JScrollPane,要實(shí)現(xiàn)起來(lái)就有點(diǎn)復(fù)雜,下面我將討論為什么它會(huì)比較難以用繼續(xù)的方式來(lái)實(shí)現(xiàn)。
  
  討論一下繼續(xù)方式實(shí)現(xiàn)Decorator模式的優(yōu)點(diǎn)與缺點(diǎn):
  
  優(yōu)點(diǎn)
  
  1 我們幾乎可以用這個(gè)方式實(shí)現(xiàn)所有的Decorator。
  
  2 使用繼續(xù)方式實(shí)現(xiàn)Decorator模式,可以保留被裝飾類(lèi)的原始類(lèi)型,這一點(diǎn)是非常重要的。用繼續(xù)方式,我們?nèi)钥梢允褂帽谎b飾類(lèi)的在被裝飾之前的類(lèi)型,例如,我們可以在我們的應(yīng)用程序中使用crollOverButton代替JButton,但是JScrollPane就不能代替包含在它內(nèi)部的對(duì)象。
  
  缺點(diǎn)
  
  1 用繼續(xù)的方式仍不夠直接。設(shè)想一下我們實(shí)現(xiàn)了ScrollOverButton和DebugButton,但是我們又需要實(shí)現(xiàn)一個(gè)既有ScrollOverButton特點(diǎn)又有DebugButton行為的按鈕。怎么辦?用繼續(xù)方式我們唯一的選擇就是再派生出一個(gè)ScrollOverDebugButton類(lèi)。
  
  假如我們有了ScrollOverDebugButton的實(shí)現(xiàn),那么是否還需要繼續(xù)保留ScrollOverButton或DebugButton實(shí)現(xiàn)?因?yàn)槲覀兛梢詾镾crollOverDebugButton增加兩對(duì)方法來(lái)打開(kāi)或關(guān)閉debug或scroll-over的行為:
  
  public void setDebug(boolean b);
  public boolean isDebug();
  
  public void setScrollOver(boolean b);
  public boolean isScrollOver();
  
  再進(jìn)一步考慮,假如將來(lái)我們有更多的裝飾功能,增加新的U1,U2,......Un個(gè)行為。我們是不是要寫(xiě)一個(gè)類(lèi),叫U1U2...UnButton?它是不是要包括2n個(gè)這樣的方法:
  
  public void setU(boolean b);
  public boolean getU;();
  
  每增加一個(gè)新的行為(Un+1)給裝飾器就需要增加兩個(gè)新的方法,并要修改這個(gè)裝飾器的代碼實(shí)現(xiàn)。這明顯與面向?qū)ο蟮乃枷胂嚆#赡軙?huì)產(chǎn)生嚴(yán)重的后果。(注重:
javax.swing.JButton就是這樣實(shí)現(xiàn)的)。
  
  2 多數(shù)可視化對(duì)象的行為是由風(fēng)格參數(shù)來(lái)指定的,而風(fēng)格的改變是不可預(yù)知的。當(dāng)風(fēng)格發(fā)生了改變,我們不得不調(diào)整自己的改變。正如上面所述,使用繼續(xù)的方式可能需要改變實(shí)現(xiàn)的代碼。
  
  3 要保證被裝飾類(lèi)的原始類(lèi)型也不是一件輕易的事。我們需要重載每個(gè)構(gòu)造子,有時(shí)甚至是靜態(tài)方式。盡管這不困難,但總是相當(dāng)麻煩的一件事。
  
  用繼續(xù)方式來(lái)實(shí)現(xiàn)Decorator模式并不象我們先前想像的那么簡(jiǎn)單。許多時(shí)候,我們并不知道將來(lái)我們需要哪一些裝飾器,結(jié)果是,使用繼續(xù)方式的Decorator在擴(kuò)展性方面相當(dāng)困難,并且與面向?qū)ο蟮脑瓌t會(huì)產(chǎn)生沖突。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 长治县| 城市| 沾化县| 始兴县| 集贤县| 中方县| 陇西县| 荣成市| 高州市| 二手房| 安平县| 子洲县| 安化县| 大荔县| 泾川县| 安顺市| 富顺县| 澎湖县| 方城县| 都江堰市| 大方县| 伊春市| 彭水| 聂拉木县| 关岭| 小金县| 阿荣旗| 滁州市| 博白县| 芮城县| 米泉市| 惠安县| 中宁县| 云阳县| 嘉义县| 三门县| 车险| 芜湖市| 荥经县| 锡林郭勒盟| 称多县|