亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java設計模式之修飾模式篇

2019-11-18 12:17:38
字體:
來源:轉載
供稿:網友

  最近我給女朋友買了一款可以更換外殼的手機。現在的外殼是紅色的,假如我想用這款手機的時候,會更換成銀灰色的外殼。但是我不能隨意更換天線或者話筒,因為這些功能模塊在手機生產的時候就已經被固定了。
  
  軟件中的修飾者(decorator),和手機的外殼一樣,封裝了一些可以替換的功能。例如下面是一段替換Swing中表模型的代碼:
  
  TableSortDecorator sortDecorator = new TableSortDecorator(table.getModel());
  table.setModel(sortDecorator);
  
  
  
  在這段代碼中,程序首先將表模型包裝在一個修飾對象中。以后當表對它的模型進行操作的時候,它實際上操作的是排序修飾對象(sortDecorator),該修飾對象在表模型中加入了排序功能,而將其他基本的功能委托給缺省的表模型,在修飾模型中,這個缺省的表模型又被稱為真實對象(real subject)。
  
  在java的編程中,基類和子類的繼續關系在編譯的時候就被固定了,就像手機的天線和話筒一樣。由于繼續關系是靜態的,開發人員無法在程序運行時改變對象的行為。但是通過修飾者開發人員可以在運行時拼裝對象,因此修飾模式提供了一種比繼續更靈活的功能擴充模式。
  
  
  修飾模式(Decorator Pattern)
  
  
  在運行時將特定的功能綁定在對象上,這就是修飾模式的核心。修飾模式比繼續更加靈活,因為后者是在編譯時就將特定的功能綁定到類上。
  
  下面然我們來看一個簡單的I/O例子:
  
  FileReader    frdr = new FileReader(filename);
  LineNumberReader lrdr = new LineNumberReader(frdr);
  
  
  
  這段代碼中創建了一個Reader:lrdr。它從一個文件中讀取數據并跟蹤文件的行號。在第一行創建的frdr對象能夠從文件中讀取數據,而第二行給lrdr增加了跟蹤行號的功能。在運行時(runtime),修飾者將方法調用傳遞給它所修飾的真實對象。在上面的例子中,lrdr將方法調用傳遞給它修飾的真實對象frdr。修飾者除了能夠進行方法傳遞外,還能夠增加類的功能。例如在上面的例子中,lrdr能夠跟蹤當前的文件流讀入數據的行號。
  
  而下面的例子顯示了如何在程序中使用修飾者lrdr。程序將數據按行從文件中讀出后,加上行號輸出到屏幕上。
  
  try {
  LineNumberReader lrdr = new LineNumberReader(new FileReader(filename));
  
  for(String line; (line = lrdr.readLine()) != null;)rticle.txt {
   System.out.PRint(lrdr.getLineNumber() + ":/t" + line);
  }
  }
  catch(java.io.FileNotFoundException fnfx) {
  fnfx.printStackTrace();
  }
  catch(java.io.IOException iox) {
  iox.printStackTrace();
  }
  
  修飾者的靜態和動態特性
  
  
  工程學上經常提到靜態和動態的概念。靜態方法研究那些變化或位移相對較小的對象,例如橋梁或建筑,而動態方法研究那些變化和移動較快的對象,例如發動機。在軟件工程中也有相應的概念,靜態方法研究在編譯時類之間的關系,而動態方法研究在運行時類參與的一些的事件。在這一節中,我將用UML類圖來展示修飾者的靜態特性,用UML時序圖來展示修飾者的動態特性。
  
  修飾者的靜態特性
  
  修飾者通過增加功能來修飾被修飾對象(Decorated,也就是真實對象)。下面的UML類圖展示了修飾者和真實對象之間的關系。
   Java設計模式之修飾模式篇(圖一)
  圖1 修飾者和被修飾者的關系
  
  
  修飾者繼續了被修飾者或者實現了被修飾者的接口,同時修飾者還保存了對被修飾者實例的引用,這個實例就是修飾者修飾的對象。為了說明這些類在到底是如何關聯的,圖2中舉了一個Java SDK的java.io.package中的實際例子。
   Java設計模式之修飾模式篇(圖二)
  圖2 一個真實的修飾模型例子
  
  
  BufferedReader和FilterReader就是圖1中演示的抽象類,他們都繼續了抽象類Reader,并且將方法調用傳遞給Reader對象。由于繼續了修飾者類,因此LineNumberReader和PushbackReader也是修飾者類。
  
  修飾者的動態特性
  
  在運行時,修飾者將方法調用傳遞給被修飾者,如圖3所示:
   Java設計模式之修飾模式篇(圖三)
  圖3 修飾者的動態特性
  
  修飾者通常將對被修飾者的調用包裝起來,圖3描述了這種特性。圖4描述了上面的I/O例子中修飾者的動態特性:
   Java設計模式之修飾模式篇(圖四)
  圖4 I/O例子中修飾者的動態特性
  
  
  現在大家對修飾模式以及它的靜態和動態特性有一個比較明確的熟悉了。讓我們通過一個完整的例子來說明如何在代碼中實現修飾模式。
  
  排序和過濾修飾
  
  修飾者主要是用于給被修飾者增加功能。在下面的例子中,我們會給Swing中的表增加排序和過濾的功能。在介紹例子之前,先簡單介紹一下如何使用Swing中的JTable類。
  
  import javax.swing.*;
  import javax.swing.table.*;
  public class Test extends JFrame {
  public static void main(String args[]) {
   Test frame = new Test();
   frame.setTitle("Swing表的例子");
   frame.setBounds(300, 300, 450, 300);
   frame.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE);
   frame.show();
  }
  public Test() {
   TableModel model = new TestModel(); 
   getContentPane().add(new JScrollPane(new JTable(model)));
  }
  private static class TestModel extends AbstractTableModel {
   final int rows = 100, cols = 10;
   public int  getRowCount()  { return rows; }
   public int  getColumnCount() { return cols; }
   public Object getValueAt(int row, int col) {
     return "(" + row + "," + col + ")";
   }
  }
  }
  
  該程序創建了一個100×10的表。表對象由三個部分組成:表模型、視圖和事件控制器。表中的數據保存在表模型中,視圖控制數據的顯示,而事件控制器控制對事件的響應。圖5是運行這個程序的結果。
   Java設計模式之修飾模式篇(圖五)
  圖5 Swing表的例子
  
  排序修飾者
  
  圖6中的應用程序包含了一張兩列的表,一列是貨物名稱,一列是價格。通過單擊列頭可以根據貨物的價格對表進行排序。下面是這個程序的代碼:
   Java設計模式之修飾模式篇(圖六)
  圖6 排序修飾者的例子
  
  //Test.java
  import java.awt.*;
  import java.awt.event.*;
  
  import java.util.Locale;
  import java.util.ResourceBundle;
  
  import javax.swing.*;
  import javax.swing.table.*;
  
  public class Test extends JFrame {
  public static void main(String args[]) {
   SwingApp.launch(new Test(), "排序修飾者",
                  300, 300, 450, 250);
  }
  public Test() {
   // 生成修飾者的實例,該實例用于修飾Swing Table原有的表模型
   // 該實例必須是final的,因為它會被內嵌類引用。
   final TableSortDecorator decorator =
      new TableBubbleSortDecorator(table.getModel());
   // 將表的模型設定為修飾者。因為修飾者實現了TableModel接口,
   // 因此Swing Table對象不知道修飾者和真實對象之間的差別。
   table.setModel(decorator);
   getContentPane().add(new JScrollPane(table),
                BorderLayout.CENTER);
   // 在界面中添加一個狀態區
   getContentPane().add(SwingApp.getStatusArea(),
                BorderLayout.SOUTH);
   SwingApp.showStatus("進行排序前");
   // 獲得對表中列頭的引用。
   JTableHeader hdr = (JTableHeader)table.getTableHeader();
   // 當單擊鼠標單擊列頭時,調用修飾者的sort()方法。
   hdr.addMouseListener(new MouseAdapter() {
     public void mouseClicked(MouseEvent e) {
      TableColumnModel tcm = table.getColumnModel();
      int vc = tcm.getColumnIndexAtX(e.getX());
      int mc = table.convertColumnIndexToModel(vc);
      // 進行排序
      decorator.sort(mc);
      // 更新狀態區
      SwingApp.showStatus(headers[mc] + " 排序中");
     }
   });
  }
  final String[] headers = { "品名", "價格/每斤." };
  JTable table = new JTable(new Object[][] {
      {"蘋果",   "1.2"}, {"芒果",  "4"},
      {"檸檬", "2.5"},{"香蕉", "0.8"},
      {"桔子",   "1.8"},

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久国产精品99国产精| 日韩高清中文字幕| 中文字幕日韩有码| 国产综合在线看| 91精品国产综合久久香蕉的用户体验| 国产精品流白浆视频| 久久91精品国产91久久久| 91探花福利精品国产自产在线| 久久精品视频导航| 久久影视免费观看| 久久精品美女视频网站| 欧美日韩国内自拍| 日韩av在线免费播放| 色综合久久精品亚洲国产| 亚洲精品小视频在线观看| 91沈先生在线观看| 欧美一级淫片videoshd| 成人激情在线播放| 久久国产精品久久久久久久久久| 色综合伊人色综合网| 日韩福利视频在线观看| 亚洲国产婷婷香蕉久久久久久| 亚洲人成电影网站色www| 亚洲精品电影网站| 欧美性猛交xxxx| 日本三级久久久| 国产午夜精品视频免费不卡69堂| 日韩高清av一区二区三区| 日韩中文字幕精品视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 日韩电影在线观看中文字幕| 亚洲欧美中文字幕在线一区| 欧美电影免费观看网站| 免费不卡欧美自拍视频| 亚洲一区二区三区在线免费观看| 国产精品va在线播放我和闺蜜| 久久久久99精品久久久久| 亚洲国产成人精品电影| 久久久99久久精品女同性| 久久视频这里只有精品| 日本电影亚洲天堂| 欧美亚洲激情在线| 亚洲伊人久久综合| 欧美日韩福利电影| 国产成人精品999| 亚洲一区二区国产| 日韩在线播放视频| 国产成人精品在线观看| 久久精品亚洲精品| 久久天天躁狠狠躁老女人| 欧美野外wwwxxx| 亚洲人精品午夜在线观看| 国产精品久久久av| 亚洲成人av片在线观看| 成人精品在线视频| 午夜精品久久久久久久男人的天堂| 亚洲2020天天堂在线观看| 国产精品久久久久久久午夜| 久久久久成人网| 日韩欧美一区二区三区| 久久久久久久久久久免费| 欧美日韩在线视频首页| 亚洲黄色成人网| 国产欧亚日韩视频| 精品中文字幕久久久久久| 精品国产福利在线| 国产欧美久久久久久| 亚洲精品美女网站| 精品久久久久人成| 91精品国产亚洲| 日韩激情在线视频| 精品一区精品二区| 国产欧美欧洲在线观看| 国模吧一区二区三区| 亚洲国产精品yw在线观看| 国产成人一区三区| 成人激情春色网| 欧美精品一区在线播放| 国产成人综合亚洲| 欧美与黑人午夜性猛交久久久| 久久中文字幕视频| 国产精品稀缺呦系列在线| 国产精品美女视频网站| 麻豆乱码国产一区二区三区| 91久久精品日日躁夜夜躁国产| 欧美美女操人视频| 欧美xxxx做受欧美.88| 中文字幕不卡在线视频极品| 国产91精品久久久久久| 中文字幕在线观看日韩| 粗暴蹂躏中文一区二区三区| 91在线精品视频| 国产精品美女在线| 中文字幕亚洲欧美日韩在线不卡| 美女av一区二区| 亚洲国产精品网站| 久99久在线视频| 欧美激情视频在线| 久久精品久久久久久| 欧美成人一二三| 91亚洲精品久久久| 亚洲精品免费一区二区三区| 97视频国产在线| 伊人久久久久久久久久| 亚洲人成在线免费观看| 国产欧亚日韩视频| 亚洲国产欧美在线成人app| 亚洲乱码国产乱码精品精天堂| 欧美伊久线香蕉线新在线| 最近更新的2019中文字幕| 国产亚洲精品久久久久久| 91免费视频国产| 欧美性猛交xxxx富婆| 大桥未久av一区二区三区| 久久久精品视频在线观看| 国产精品一区二区三区久久久| 中文字幕亚洲欧美日韩在线不卡| 亚洲欧美日韩中文视频| 中文字幕av日韩| 久久精品国产精品亚洲| 色小说视频一区| 中文字幕亚洲综合久久筱田步美| 亚洲成人黄色在线观看| 欧美精品久久久久a| 国产亚洲精品va在线观看| 精品视频中文字幕| 午夜剧场成人观在线视频免费观看| 亚洲人在线观看| 国产视频精品xxxx| 国产精品福利无圣光在线一区| 一本色道久久88亚洲综合88| 色悠久久久久综合先锋影音下载| 成人免费xxxxx在线观看| 欧美高清不卡在线| 亚洲毛片在线观看.| 久久久久久久久久久成人| 色噜噜国产精品视频一区二区| 日韩免费不卡av| 91精品国产91久久久久久| 精品久久久久久久大神国产| 91av视频在线播放| 日韩精品久久久久久福利| 欧美激情亚洲综合一区| 精品美女国产在线| 亚洲最大福利视频| 美女久久久久久久久久久| www.精品av.com| 欧美国产日本在线| 国产精品无码专区在线观看| 在线观看欧美www| 欧美另类暴力丝袜| 国产午夜精品全部视频播放| 日韩在线观看免费全| 欧美性色视频在线| 久久精品国产一区| 97人洗澡人人免费公开视频碰碰碰| 久久精品99久久久香蕉| 欧美精品久久久久久久免费观看| 韩国福利视频一区| 国产成人啪精品视频免费网| 久久亚洲欧美日韩精品专区| 亚洲第一区中文字幕| 992tv成人免费影院| 久久露脸国产精品|