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

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

使用Decorator模式 翻譯者:Disneytiger

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

  使用Decorator模式
  java程序員知道可以通過擴展一個類來改變類的行為和擴展一個類的功能。這個行為被稱為繼續,它是面向對象編程的一個重要的特性.
  舉例來說,假如你想得到一個帶有邊框的Swing類型標簽,你可以子類化javax.swing.JLabel類。然而,子類化并不總是有效。當繼續不能解決問題的時候,你不得不求助與其它的方式。比如,使用Decorator模式。
  這篇文章解釋了Decorator模式是什么,并說明什么時候應該子類化,什么時候應該采用Decorate模式。
  在Java語言中要害字extends被提供來子類化(擴展)一個類。具有豐富的面向對象編程經驗的程序員知道子類化的威力。通過擴展一個類,我們能夠改變這個類的行為。以列表1所講的JBorderLabel類為例,它擴展了javax.swing.JLabel類,除了多了一個邊框,它和JLabel類具有相同的外觀和行為。
  the JBorderLabel class, an example of subclassing
  package decorator;
  
  import java.awt.Graphics;
  import javax.swing.JLabel;
  import javax.swing.Icon;
  
  public class JBorderLabel extends JLabel {
  
  public JBorderLabel() {
  super();
  }
  
  public JBorderLabel(String text) {
  super(text);
  }
  
  public JBorderLabel(Icon image) {
  super(image);
  }
  
  public JBorderLabel(String text, Icon image, int horizontalAlignment) {
  super(text, image, horizontalAlignment);
  }
  
  public JBorderLabel(String text, int horizontalAlignment) {
  super(text, horizontalAlignment);
  }
  
  PRotected void paintComponent(Graphics g) {
  super.paintComponent(g);
  int height = this.getHeight();
  int width = this.getWidth();
  g.drawRect(0, 0, width - 1, height - 1);
  }
  }
  要理解JBorderLabel如何工作,我們首先要了解Swing繪它的組件的原理。 JLabel類同其它的Swing組件一樣,繼續至javax.swing.Jcomponent.Swing。它們都是通過調用JComponent組件的paint方法來畫界面。我們可以通過重載JComponent的公開方法paint來修改一個組件畫界面的行為。下面是一個JComponent的paint方法的定義。
  public void paint(Graphics g)
  作為paint方法的參數傳進來的對象Graphics是一個繪圖面板。為了優化繪圖這個操作,paint方法被分割成三個具有保護(protected)屬性的方法:paintComponent, paintBorder, paintChildren。paint方法調用這三個方法同時將它接受到的Graphics實例傳遞給這三個方法。下面是這三個函數的一個聲明:
  protected void paintComponent(Graphics g)
  protected void paintBorder(Graphics g)
  protected void paintChildren(Graphics g)
  你可以通過重載這些方法來定制你自己的繪制組件的方式。
  JBorderLabel類重載了javax.swing.JComponent的paintComponent方法。類JborderLabel的paintComponent方法首先調用父類的paintComponent得到一個Jlabel.它保持了自己的長和寬,通過java.awt.Graphics實例的drawRect方法畫一個矩形。圖1顯示了一個JBorderLabel類的一個實例。正如圖所示的一樣,出了多了一個邊框外,它和JLabel外觀是一樣的。
  這個例子中子類化工作得相當好。我們來看看子類化不合適的案例。假如你打算讓其它的組件都具有同一行為(比如:畫一個邊框),那么你必須做很多的子類化操作。在列表1中,子類化看起來很簡單是因為例子中你僅僅需要重載一個方法。當你有太多的子類需要創建時你的代碼將變得很復雜,出錯的機會也增大了。(你必需要復制(reprodUCe)你的子類需要支持的父類的構造函數,就像JBorderLabel類一樣)。在這個時候,最好的方式是使用Decorator模式。
  
  Decorator模式
  在Erich Gamma等編寫的《Design Patterns : Elements of Reusable Object-Oriented Software》一書中,Decorator模式被歸類為結構模式。Decorator模式提供了子類化的一個替代方案。子類化和Decorator模式的主要區別是:采用子類化,你同一個類打交道;使用Decorator模式,你可以動態的修改多個對象。當你擴展(Extend)一個類的時候,你對兒子類的改變將會影響到這個兒子類所有的實例。采用Decorator模式,你所作的改變只會影響到你打算改變的那個對象。
  理解JComponent類對于書寫裝飾者類很重要,我們通過這個裝飾者類來改變Swing組件的用戶界面。在前面部分我解釋了JComponent是如何畫它的用戶界面的,我們可以通過文檔查找來了解這個類的所有的成員。我們要意識到JComponent有子組件,當JComponent被畫的時候,這些子組件也將被畫。
  創建一個從JComponent擴展過來的Swing裝飾者。這個裝飾者的構造函數接受一個類型為JComponent的參數??梢詡鬟f任一一個需要改變行為的Swing對象給裝飾者。這個裝飾者將傳進來的這個組件作為自己的子組件。并不是直接將Swing組件增加到JFrame或JPannel或其它容器,而是先將Swing組件添加到修飾者,再把修飾者增加給容器類。因為一個修飾者也是一個JComponent類型的對象,容器不能將他們區分開來。這個裝飾者是這個容器的一個子組件。當容器讓裝飾者重畫的時候,這個裝飾者paint方法將被調用。
  舉例來說,假設你有一個JLabel類,你打算把它傳給一個稱之為frame1的JFrame類。使用如下相似的代碼:
  frame.getContentPane().add(new JLabel("a label"));用MyDecorator來修飾JLabel的代碼和它很相似,如下:(記住,MyDecorator類的構造函數應該接受一個JComponent類的輸入參數)
  frame.getContentPane().add(new MyDecorator(new JLabel("a label")));
  這篇文章示例了兩個Decorator模式的例子。第一個例子是BorderDecorator.這個類被用來修飾JComponent,以便讓JComponent具有一個邊框。當把一個由BorderDecorator修飾的JLabel增加到JFrame,這個JLabel看起來就像JBorderLabel的一個實例。這說明,子類化不是必須的。更好的是,你能夠傳遞任何一個Swing組件給BorderDecorator,這些被傳遞的組件都會給予一個邊框。在這個例子中,通過創建了一個類BorderDecorator來改變不同類型的實例的行為。
  第二個例子是ResizableDecorator。這個裝飾著為每一個傳給它的Swing組件增加一個小按鈕到左上角。當用戶點擊這個按鈕的時候,這個組件將會最小化為這個按鈕。
  
  BorderDecorator類
  我們以BorderDecorator開始。這個類表示的裝飾者會為Swing組件增加一個邊框。示例代碼如列表2
  the BorderDecorator class
  package decorator;
  
  import javax.swing.JComponent;
  import java.awt.Graphics;
  import java.awt.Color;
  import java.awt.BorderLayout;
  
  public class BorderDecorator extends JComponent {
  
  // decorated component
  protected JComponent child;
  
  public BorderDecorator(JComponent component) {
  child = component;
  this.setLayout(new BorderLayout());
  this.add(child);
  }
  
  public void paint(Graphics g) {
  super.paint(g);
  int height = this.getHeight();
  int width = this.getWidth();
  g.drawRect(0, 0, width - 1, height - 1);
  }
  }
  注重,這個BorderDecorator擴展了JComponent,它的構造函數接受一個JComponet類型的參數。這個BorderDecorator類有一個類型為JComponent的屬性child,它是傳進來的Jcomponent對象的一個引用。
  構造函數將被修飾的組件賦值給child變量,并且將這個組件作為一個子組件增加給裝飾者。注重,我們使用了BorderLayout作為裝飾者的布局。這意味著被增加的這個JComponent將占據這個裝飾者的整個區域。
  現在,讓我們關注一下paint方法。它首先調用了父類的paint方法。這-步操作將畫出裝飾者,在第一次得到裝飾者的長寬以后,我們在裝飾者所在區域的邊緣畫一個長方形。
  Figure 1 shows a JFrame with three components:
  • An instance of JBorderLabel.
  • A decorated JLabel.
  • A decorated JCheckBox.
  
  Figure 1 -- comparing subclassing and the Decorator pattern
  JBorderLabel的一個實例和一個被裝飾過的JLabel對象實例從外表看沒有什么不同。這說明,Decorator模式可以作為子類化的一個替代方案。第三個組件證實,你能夠使用同一個裝飾者去擴展不同對象的實例的行為。從這點來看,裝飾者是一個(超類)superior,因為僅僅需要創建一個類(BorderDecorator)就可以擴張不同類型的多個對象的功能。
  顯示了圖1中的JFrame類的實現代碼。
  -- using the BorderDecorator class
  package decorator;
  
  import java.awt.*;
  import javax.swing.*;
  import java.awt.event.*;
  
  public class Frame1 extends JFrame {
  
  JBorderLabel label1 =
  new JBorderLabel("JLabel Subclass");
  
  BorderDecorator label2 =
  new BorderDecorator(new JLabel("Decorated JLabel"));
  
  BorderDecorator checkBox1 =
  new BorderDecorator(new JCheckBox("Decorated JCheckBox"));
  
  public Frame1() {
  try {
  this.setDefaultCloSEOperation(EXIT_ON_CLOSE);
  getContentPan

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕亚洲欧美日韩高清| 国产91对白在线播放| 欧美超级乱淫片喷水| 亚洲欧美日本精品| 欧美激情国产高清| 精品久久久久久中文字幕一区奶水| 亚洲人成77777在线观看网| 亚洲一区二区三区在线视频| 45www国产精品网站| 尤物yw午夜国产精品视频明星| 在线观看欧美www| 亚洲图片欧美午夜| 精品国产一区av| 人妖精品videosex性欧美| 亚洲日本欧美日韩高观看| 亚洲精品中文字| 国产精品va在线| 国产精品日韩欧美大师| 国产午夜精品全部视频播放| 亚洲色图日韩av| 日韩欧美国产免费播放| 成人黄色激情网| 国产欧美韩国高清| 91国内免费在线视频| 国模精品系列视频| 中文字幕亚洲欧美日韩在线不卡| 一本大道久久加勒比香蕉| 欧美日韩成人黄色| 久久久久久伊人| 色噜噜亚洲精品中文字幕| 精品成人在线视频| 日韩欧美在线播放| 亚洲深夜福利网站| 欧美日韩另类字幕中文| 色噜噜狠狠狠综合曰曰曰88av| 日韩在线播放视频| 久久视频在线播放| 国产精品美乳在线观看| 欧美精品免费在线观看| 国产美女久久精品| 久久久久久久久久久国产| 亚洲男人天堂视频| 午夜精品视频在线| 欧美日韩国产中字| 亚洲高清久久久久久| 色樱桃影院亚洲精品影院| 日韩精品亚洲视频| 国产性猛交xxxx免费看久久| 国产精品成人v| 最近日韩中文字幕中文| 久久久久久久久网站| 欧美视频免费在线观看| 国产综合色香蕉精品| 91超碰中文字幕久久精品| 日韩欧美在线观看| 亚洲日本成人网| 亚洲天堂免费视频| 97在线免费视频| 国产精品美女免费视频| 欧美专区国产专区| 亚洲福利视频专区| 亚洲最大av网站| 亚洲国产另类 国产精品国产免费| 国产精品中文字幕在线| 亚洲欧洲成视频免费观看| 红桃av永久久久| 亚洲人成电影在线| 欧美特级www| 91精品国产综合久久久久久久久| 国产精品网站入口| 久久亚洲精品一区二区| 亚洲人成啪啪网站| 欧美香蕉大胸在线视频观看| 精品视频在线播放| 欧美精品免费在线| 日韩av一区二区在线观看| 在线日韩日本国产亚洲| 国产成人自拍视频在线观看| 日日狠狠久久偷偷四色综合免费| 欧美在线性爱视频| 亚洲黄页网在线观看| 国产一区二区精品丝袜| 国产亚洲精品久久久久久| 日韩精品视频免费在线观看| 亚洲精品电影网在线观看| 欧美成人午夜视频| 欧美日韩不卡合集视频| 一本大道久久加勒比香蕉| 欧美成人免费视频| 亚洲最大av网| 色偷偷88888欧美精品久久久| 国外视频精品毛片| 亚洲激情在线观看视频免费| 国产精品视频一区二区高潮| 国产视频自拍一区| 中文字幕亚洲自拍| 日韩在线中文字| 国产精品1区2区在线观看| 久久久久国产精品www| 日本电影亚洲天堂| 欧美日韩高清在线观看| 成人免费网站在线| 亚洲国产成人精品电影| 在线成人激情视频| 欧美性一区二区三区| 色妞欧美日韩在线| 久久免费成人精品视频| 亚洲激情视频在线观看| 一区二区三区黄色| 日本一区二区在线免费播放| 狠狠色噜噜狠狠狠狠97| 欧美午夜片欧美片在线观看| 蜜臀久久99精品久久久无需会员| 91av成人在线| y97精品国产97久久久久久| 成人在线免费观看视视频| 中文字幕亚洲天堂| 亚洲自拍欧美另类| 亚洲欧洲视频在线| 国产97在线|日韩| 国产一区二区三区在线视频| 91网在线免费观看| 91av国产在线| 久久av中文字幕| 55夜色66夜色国产精品视频| 久久久久久久国产精品视频| 色偷偷888欧美精品久久久| 欧美三级xxx| 日韩在线视频观看正片免费网站| 亚洲欧美激情四射在线日| 国产综合久久久久久| 亚洲综合最新在线| 亚洲成人激情在线观看| 91国自产精品中文字幕亚洲| 2019亚洲日韩新视频| 日韩中文字幕网址| 日韩亚洲综合在线| 成人h视频在线观看播放| 亚洲a级在线播放观看| 成人国产精品日本在线| 欧美性猛交xxxx乱大交极品| 538国产精品一区二区免费视频| 97人人做人人爱| 国产一区二区久久精品| 日韩精品在线播放| 久久久亚洲影院你懂的| 久久精品国产久精国产思思| 成人妇女淫片aaaa视频| 日韩亚洲欧美成人| 日韩欧美综合在线视频| 8090成年在线看片午夜| 亚洲视频在线免费观看| 91在线观看免费网站| 亚洲福利在线播放| 欧美成人免费播放| 一区二区av在线| 国产不卡在线观看| 久久精品视频中文字幕| 精品视频—区二区三区免费| 日韩欧美在线字幕| 欧美日韩亚洲一区二| 精品久久久久久亚洲国产300| 亚洲午夜激情免费视频| 国a精品视频大全|