修飾者的靜態和動態特性
工程學上經常提到靜態和動態的概念。靜態方法研究那些變化或位移相對較小的對象,例如橋梁或建筑,而動態方法研究那些變化和移動較快的對象,例如發動機。在軟件工程中也有相應的概念,靜態方法研究在編譯時類之間的關系,而動態方法研究在運行時類參與的一些的事件。在這一節中,我將用UML類圖來展示修飾者的靜態特性,用UML時序圖來展示修飾者的動態特性。
修飾者的靜態特性
修飾者通過增加功能來修飾被修飾對象(Decorated,也就是真實對象)。下面的UML類圖展示了修飾者和真實對象之間的關系。
修飾者繼承了被修飾者或者實現了被修飾者的接口,同時修飾者還保存了對被修飾者實例的引用,這個實例就是修飾者修飾的對象。為了說明這些類在到底是如何關聯的,圖2中舉了一個Java SDK的java.io.package中的實際例子。
BufferedReader和FilterReader就是圖1中演示的抽象類,他們都繼承了抽象類Reader,并且將方法調用傳遞給Reader對象。由于繼承了修飾者類,因此LineNumberReader和PushbackReader也是修飾者類。
修飾者的動態特性
在運行時,修飾者將方法調用傳遞給被修飾者,如圖3所示:
修飾者通常將對被修飾者的調用包裝起來,圖3描述了這種特性。圖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是運行這個程序的結果。
圖5 Swing表的例子
排序修飾者
圖6中的應用程序包含了一張兩列的表,一列是貨物名稱,一列是價格。通過單擊列頭可以根據貨物的價格對表進行排序。下面是這個程序的代碼:
圖6 排序修飾者的例子
(未完待續)
文章來源于領測軟件測試網 http://www.kjueaiud.com/