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

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

使用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的參數。可以傳遞任一一個需要改變行為的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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹江口市| 府谷县| 宁都县| 铁力市| 龙里县| 柯坪县| 平顶山市| 乐安县| 平遥县| 饶平县| 永修县| 岳阳市| 长春市| 铜梁县| 唐河县| 马龙县| 香河县| 句容市| 分宜县| 鄢陵县| 红安县| 福鼎市| 杭锦后旗| 余庆县| 江西省| 万宁市| 巩义市| 永仁县| 瑞安市| 岫岩| 唐河县| 略阳县| 新乐市| 郓城县| 宜良县| 张家界市| 东辽县| 怀来县| 万州区| 葫芦岛市| 定边县|