使用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;
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;