2. 背景知識
2.1 Java annotation
Java 系統在 1.5 版之後加入了 annotation 的功能[9]。Annotation 與本來就有的 註解有何不同呢?我們整理在表 2-1 中。
Kind
範例 特性Single line comment Or
Block comment
//comment Or
/* comment */
1. 存在原始碼中 2. 只被設計人員辨識
Documentation comment
(Javadoc)
/**
* @information
*/
1. 存在原始碼中 2. 可被轉換成文件
Annotation @annotation_name() public string toString(){
….
第一類的single line comment 以及 block comment,程式設計人員編寫的註解只 會存在於原始程式碼當中,目的在於對其他的程式設計人員解釋程式碼的意義。
此類註解只會被人所辨識,編譯器不會對它有任何的動作。
第二類的documentation comment 必須合乎特定的文法規則,由符號/**開始。
這類的註釋可以利用外部的應用程式javadoc 解讀註釋然後產生出說明文件,最常 見的是html 的格式。
第三類的annotation 則是一個可被進一步的處理,annotation_name 必須事先被 程式設計人員定義。然後程式開發者可以把此annotation 當做 modifier,放在原來 的Java 程式中可以放置 modifier 的位置,比如 class、method 等宣告之前。
7
Annotation 的重點在於不只存在於原始程式碼,編譯時我們還可以把它保存在 class 檔中,甚至可以在執行時被使用到。APT[9]是一個提供程式開發者自行處理 Java annotation 的工具,程式開發者可以利用 APT 來設計對 annotation 處理的程序,
這個程序將會在程式碼編譯前進行。
J
9
2.3 NetBeans IDE
NetBeans[5]是由 Sun Microsystems 建立的開放原始程式碼的軟體開發工具,
而且具有開放框架、可擴充功能的開發平台,可用於對Java、C、C++等語言的開 發。在NetBeans 當中,應用軟體是用一系列的模組(modular software components)[10]
所建構,UML 的功能便是其中一種模組。
NetBeans UML 提供圖形化的使用者介面(如圖 2-2),使用者在編輯 UML 是
以操作圖形的方式進行,有如繪圖一般的進行。使用者可對UML 中的每個元件,
如物件、關係等等,進行更深入的設定。
圖 2-2 : NetBeans UML 設計介面
10
NetBeans UML 還提供使用者直接引入一套 design pattern 的功能。在使用者 進行 design pattern 的選擇與設定之後,便會在 class diagram 中產生一套 design pattern UML,讓使用者省去對照著 GOF 的設計,快速繪製出 design pattern 的 UML 圖形。
NetBeans UML 最後可以產生只有宣告和定義的框架程式碼,可將程式碼生 成於 NetBeans 正在開啟程式專案,產生的程式碼會實現 UML 中編輯的關係,像 是class 之間的 inheritance、association、aggregation,class 對於 interface 的實作等 等。
2.4 NetBeans 內部設計
2.4.1 UML 資料結構
NetBeans UML 雖然是用圖型的介面呈現,但是 NetBeans 的內部實作上,UML 的資料結構是以 XML 文件進行紀錄。UML 中的任何一個物件與關係,都將由一 個 XML node 所記錄,包含當中的進階資訊。使用者所做的任何圖形編輯,都在 NetBeans 的模組功能下轉變為對 XML 文件的修改。紀錄 UML 的 XML 樹狀結構 大致可以如下定義:
<UML:資料類型 資料資訊=??>
除了NetBeans 自行定義的資料類型,資料類型大多是 UML 圖形中可以看到 的元素。表 2-2 列出了我們所知的資料類型,其中包含了一般 UML 定義的元件[4]
和NetBeans 自身的專案資料。資料資訊(表 2-3)則是用來描述資料類型的資訊。
11
用於
UML 元件的資料類型
Interface 紀錄Interface 的資訊
Class 紀錄Class 的資訊
Enumeration 紀錄enumeration 的資訊
Operation 紀錄Method 的資訊
Parameter 紀錄parameter 的資訊
Attribute 紀錄Field 的資訊
Package 紀錄Package 的資訊
用於
UML 關係的資料類型
Implementation 紀錄Class impalements Interface 的資訊
Aggregation 紀錄Aggregation 的資訊
Association 紀錄Association 的資訊
Dependency 紀錄Interface Dependency Class 的資訊
Comment 紀錄Comment 的資訊
Generalization 紀錄Class extends Class 的資訊
NetBeans 自定義的資料類型
Project UML 所屬的 project 資訊
Element UML 中元件有包含的特性,則會用
Element 將之涵蓋
TaggedValue 紀錄UML 編輯上的額外資訊
表 2-2 : UML node 資料類型
UML
ub element ( 所示,singleC13
MethodReturnInt 和 field1。element C , D , E 如同 element A,它們的 attribute 記錄 著本身的資訊。
NetBeans UML 模組在管理 UML 元件時有特定的格式,UML 元件(參考表 2-2) 若包含其它元件資訊,便集中管理於XML element <UML:Element.ownedElement>。
若這個element 不存在,便會建構它,在存入此 element。圖 2-3 的 element A 和 E 便是例子,它包含其它的元件資訊,因此這兩個node 都有<UML:Element.owned- Element>此 element node 來儲存更深入的元件資訊。
NetBeans UML 模組還具有一個重要的功能,就是提供使用者直接引入一套 design pattern 的 UML diagram。這項功能在使用者輸入要引用的 pattern 名稱後,
可直接建造出該pattern 的 diagram,而省去使用者自行編輯 design pattern diagram 的步驟。事實上design pattern 的 XML 是一個外部的檔案,NetBeans 再引入使用 者所選取的design pattern diagram,此引入的動作即是從檔案取一份拷貝。
2.4.2 生成原始程式碼
NetBeans UML 提供了將 UML diagram 轉變成程式碼的功能。使用者在設計 完UML 之後,可以選擇將 UML diagram 產生成框架程式碼,框架程式碼是一份 只有架構的程式碼,程式中的邏輯和方法都尚未實做。接著NetBeans IDE 會將程 式碼產生在使用者所選擇的專案當中。
使用者選擇了產生程式碼的選項後,NetBeans 會呼叫 code generate 模組的程 序。在這個程序當中會以UML 中的 class,interface 和 enumeration 為一個檔案單 位,產生相對應的Java 檔案。產生程式碼的過程中,code generate 的程序會讀取 UML diagram 的內容,也就是 XML 文件,將一個 class(或者是 interface、enumeration) 的資訊進行整合,然後產生一個ClassInfo 的物件。ClassInfo 是一個用於描述 Java 類別的資料類別(metaclass),ClassInfo 主要功能在於傳遞 NetBeans 的模組之間所 需要的類別資訊。ClassInfo 的成員由的類別內容可以得知,此類別描述與紀錄 UML
14
當中一個 class 的完整資訊。
ClassInfo 物件除了用於紀錄類別資訊,UML 中的 operation、attribute 等其他 相關元件都有相關的類別來紀錄它們的資訊,如 MethodInfo 類別和 MemberInfo 類別。而這些類別的物件都會被ClassInfo 物件所參照。
ClassInfo 物件雖然記錄了 Java 檔案的大部分內容,但 Java 檔案的內容並不 是由ClassInfo 所產生。code generate 程序在完成了 ClassInfo 物件之後,會將物件 傳給樣板引擎:FreeMarker([13])。FreeMarker 是一個會根據樣板產生文件的工具,
而FreeMarker 所引用的樣板文件(表 2-4)可從 NetBeans 的 templete tool 中編輯。
FreeMarker 利用樣板文件和 ClassInfo 物件的資訊產生相對應的 Java 檔案。
<#--
NormalClassDeclaration -->
<#import "DeclLib.ftl" as lib />
<#macro NormalClassDeclaration classInfo nestingLevel
>
<@lib.TypeDeclarationComment classInfo nestingLevel />
<@lib.ident nestingLevel /><@lib.compress single_line=true >
<@lib.TypeDeclarationModifiers classInfo /> class ${classInfo.getShortClassName()}
<@lib.TypeDeclarationTypeParameters classInfo /> <@lib.NormalClassExtends classInfo />
<@lib.ClassImplements classInfo /></@lib.compress> {
<@lib.ClassBodyDeclaration classInfo nestingLevel+1 />
<@lib.ident nestingLevel />}
</#macro>
表 2-4 : class 樣板文件內容
3.
的state patt 使用State 的GOF state patte
時,可以引
儲存與
gn pattern 的 段就要進行資 入design patt
用此儲存de
用Java annot 錄。在這個章
16
在UML 當中運用 state pattern 的概念。程式開發者雖然應用 design pattern 的概念,
但是在類別與方法的命名上,還是取決於程式開發者設計上的想法,因此UML 設
計完成後我們很難從它的名稱和架構來判斷它所使用的 design pattern。圖 3-2 是 命名過後的 state pattern,除了 interface 的名稱有 state 的文字以外,其它的 GOF 命名都不存在於設計中。
圖 3-2 : 經過命名後的 state pattern
我們所希望保存的design pattern 資訊,便是引用 design pattern 時各個元件所 代表design pattern 的角色。以圖 3-2 的案例來說,類別 Door 是原先 state pattern 的類別Context、interface DoorState 是原先 state pattern 的 abstrct 類別 State 而類別 OPEN 和 CLOSE 則是原先 state pattern 的類別 ConcreteState;同樣的方法(method) 亦可類推。
我們將在後續介紹如何在NetBeans UML 中儲存 design pattern 資訊。我們所 要保存的資料是能夠讓程式到產品化階段仍能夠判別出interface DoorState 是 state pattern 設計中的 abstrct 類別 State。
3.2 Design Pattern 資訊儲存
NetBeans UML 的內部資料結構是一個 XML 文件,根據 design pattern 的設計,
17
每個interfaces、classes、methods 和 variables 都可能在 design pattern 中扮演一個角 色。因此在XML 文件當中每個描述 interfaces、classes、methods 和 variables 的 xml node 都要能夠追加描述 design pattern 資訊的欄位。我們選擇利用 NetBeans 現有的 XML element <UML:TaggedValue>,然後利用這個 node 來紀錄 design pattern 的資 訊。按照2.4.1 的介紹,element <UML:TaggedValue>是 element <UML:Element.
ownedElement>的一個 sub element。
紀錄design pattern 資訊的 XML element 如表 3-1 定義之,其中的黑體字是我 們要填入的資訊。PatternType 可以被使用者編輯,但它的內容在後續規定,Pattern- Info 則任由使用者編輯,它的內容將會是 design pattern 的資訊。
-<UML:TaggedValue xmi.id="idformIDE" owner=" idformIDE " name="PatternType">
<UML:TaggedValue.dataValue>PatternInfo</UML:TaggedValue.dataValue>
</UML:TaggedValue>
表 3-1 : 紀錄 design pattern 資訊的 XML element
PatternType 所表達的 UML 元件 PatternType 的內容
Interface、Class or Enumeration patternClass
Operation patternOperation
Attribute pattern Attribute
表 3-2 : 對應 UML 元件類型的 PatternType 內容
xmi.id 和 owner 將由 NetBeans 自行創建,並且內容由 NetBeans 負責管理,
而name 這個 attribute 用來紀錄 PatternType,PatternType 是此 XML element 所描述 的元件類型,PatternType 的內容如表 3-2 的方式定義。PatternInfo 是 node 的內容,
用來紀錄此元件的 design pattern 資訊。以圖 3-2 的類別 OPEN 為例子,它的 PatternType 的 內 容 將 會 是 “patternClass” , 而 PatternInfo 的 內 容 則 為
“ConcreteState”。PatternType 的內容取決於此 element 所描述的元件類型,由表 3-2
18
定義;而PatternInfo 的內容將表達此元件在 design pattern 中扮演的角色,按照圖 3-1 與圖 3-2 的對應,PatternInfo 的內容為”ConcreteState”,因為類別 OPEN 代表 的是 ConcreteState,它必須實做 abstrct 類別 State。表 3-3 將描述類別 OPEN 在 UML 中所帶有的 design pattern 資訊,這是利用<UML:TaggedValue>來記錄資訊。
-<UML:TaggedValue xmi.id="idformIDE" owner=" idformIDE " name=" patternClass ">
<UML:TaggedValue.dataValue> ConcreteState </UML:TaggedValue.dataValue>
</UML:TaggedValue>
表 3-3 : 類別 OPEN 的 design pattern 資訊
利 用 <UML:TaggedValue> 紀 錄 design pattern 資 訊 的 主 要 原 因 是
<UML:TaggedValue>這個 node 是 NetBeans 本身提供給使用者編輯的欄位。使用
<UML:TaggedValue>紀錄 design pattern 資訊的好處是使用者可以利用 NetBeans 現 有的介面直接進行編輯,而省去我們修改NetBeans UI 的麻煩。另一個好處是因為
<UML:TaggedValue>可以有兩個以上,依照程式開發者設計的不同,同樣的 UML 元件可能同時扮演著design pattern 中的兩個角色;另一個重要的原因是,UML 在 生成source code 時,我們將利用 java annotation 來記錄此資訊,同樣的兩個以上的 java annotation 可以同時描述於一個類別(或其他元件)。根據 UML 設計上的要求與 java annotation 的特性,<UML:TaggedValue>符合我們的需求,因此利用它來記錄 design pattern 資訊。
上述是利用 element <UML:TaggedValue>來記錄 design pattern 資訊。因為
<UML:TaggedValue>是一個可以編輯的欄位,為了避免使用者的錯誤編輯,我們另 外設計了一個XML attribute 來記錄 design pattern 資訊,而這個 node 將無法被使用 者所編輯。
紀錄annotation 的 XML attribute 如表 3-4 定義之,其中的黑體字是我們要填 入的內容,但使用者並不能編輯。
19
<UML:(UML 元件) xmi.id=" idformIDE " name="editByUser" isAbstract=" editByUser "
owner="idformIDE" PatternType =" PatternInfo ">
表 3-4 : 紀錄 design pattern 資訊的 XML attribute
PatternType 與 PatternInfo 的內容與 element(表 3-1)的定義相同,差別在於 PatternType 將轉為 attribute 的名稱,PatternInfo 將會是 attribute 的內容。同樣的對
PatternType 與 PatternInfo 的內容與 element(表 3-1)的定義相同,差別在於 PatternType 將轉為 attribute 的名稱,PatternInfo 將會是 attribute 的內容。同樣的對