• 沒有找到結果。

JavaBean 介紹

在文檔中 軟體評估工具 (頁 29-0)

第四章 相關技術研究

4.1.1 JavaBean 介紹

"A Java Bean is a reusable software component that can be manipulated visually in a builder tool."上面的這句話是 JavaBeans Specifcation 對 Java Bean 的定義。舉例來說,在 Java 1.1 裡一個單獨的 AWT Component 都是一個 Bean.我們可以透過一些 tools,如 IBM 的 Visual Age J++,Borland 的 JBulider,或是 Sun 的 BDK 等等的 editors,來幫我們使用這些 components。

• 目的

1. 如果是要發展一些 GUI editors,application buliders 等等,或是要做一個實際可用的 Java Bean,那就必須要 對 JavaBean API 很熟。

2. 如果是利用一些如 JBuilder 的 editor 來使用 Java Bean,或是來發展 applications,那可以不必對 JavaBean API 做太深入的研究(也就是說不用去理它),只要對所使

o 一個支援 Java Bean 的 GUI visual editor,因為 Java Bean 或多或少都會有 GUI 介面,所以有一個這樣的工具,

不但可以測試你所寫的 Java Bean,還可以節省你開發的 時間。

• 如何寫一個 Java Bean

0. Java Bean 並不像 Applet,必須繼承一個 Applet 的 class,雖然 Java Bean 也有一個叫 Beans 的 class 可供 繼承,但是並不強迫一定要繼承.另一方面雖然很多的 Beans 是 AWT 的 Components,但是你也可以寫一個不會 show 任何東西在螢幕上的 Bean(但是可以被你的 edit tool 看見,例如一個 sound player)。

1. A Bean exports

properties

,

events

,and

methods

.

ƒ Bean 的結構

(圖十二 Bean 結構圖)

ƒ Properties:

一個 Bean 的 properties 描述該 Bean 的屬性,如顏 色,大小,或是 label 等等。Properties 通常透過一 對 methods 如 set<property> / get<property>來 改 變 / 取得 此 property。

ƒ Methods:

和一般的 Java methods 一樣,不過在 Java Bean

o Introspection:

利用一些 rule 來讓你的 Java Bean 提供的 methods 可 以被 builder tool 來看見。它是依照下面幾個 rules 來 搜尋 。

o Bean 的 Methods:

它會把 public getXXXXX/setXXXXX 以及 boolean isXXXXX 的 methods 找出來。接著把你宣告成 public 的 methods 也挖出來。然後它會尋找有加 BeanInfo 的 class 名稱(Ex: 如果你的 Java Bean 叫myBean,那

myBeanBeanInfo 就是它搜尋的目標)。

o Persistence:

利用 Object Serialization 的機制來 Save/Load Java Bean 的狀態改變。

o Customization:

當我們製作一個大型的 Java Bean(或是複雜一點 的),光是用 set/get 的方法來改變 properties 是不夠 的,因此 Java Bean 提供一個 customizer 的 class 來自 己定義一些改變 properties 的方法。

4.2 APPLICATION 部分 4.2.1 JavaNCSS 介紹

• 說明:JAVANCSS 為一個免費自由軟體,其網址為

http://www.kclee.com/clemens/java/javancss/

,此軟體可分 析程式架構,算出各類 METRIC,並可將所算出的結果存成 XML 格式

• JavaNCSS 架構

• JavaNCSS 依檔案分為兩部分:

o parser 部分:由 JavaCC 所產生的程式碼,而 Java1.1.jj 就是

指主文件

ASCII_UCodeESC_CharStream.java JavaParser.java JavaParserConstants.java

JavaParserTokenManager.java ParseException.java Token.java TokenMgrError.java

o 主程式部分:

XmlFormatter.java AsciiFormatter.java Formatter.java Javancss.java

JavancssAntTask.java JavancssConstants.java JavancssFrame.java Main.java

PackageMetric.java

• JavaNCSS 分析結果

J

avaNCSS 雖已有我們專題所需做到的結果,但其程式碼改寫不 易,由於之前改寫的為一個的德國人,其註解不是看不懂,就是德文 字碼無法顯示,使得可讀性很低,加之其很多部分為用到 JavaCC 的 文件,使的我們讀起來格外吃力,故我們讀完後放棄以改寫此軟體的 做法,只採用其系統的粗略架構,如 parser 的做法、類別的切割方 式…等,並重新規劃構想,簡化設計,將系統設計成只要做到查出 class、function…等 METRIC,所以由 Java1.1.jj 產生的 parser 類 別可以簡略,改以自己編寫,而輸出輸入格式,也都定為 java 原始 檔,故也可將之簡化,但界面部分,由於要求以圖形介面,再加以強 化擴充。

4.3 Metrics 計算部分

因為我們計算 Metrics 的部分是利用 JavaCC 這個工具,而且該 工具還利用到了一些 Design Pattern,如存放 syntax tree 時用到 Composite Pattern,要對 tree 做處理時要利用 Visitor Pattern,

有關這部分的觀念技術,簡述如後。

4.3.1 JavaCC 介紹

JavaCC 是 Java complier-complier 的縮寫,這是一個 Parser 和 lexical analyzer 產生器。JavaCC 會讀進一個語言敘述,產生 java 程式碼。產生出來的程式碼經過編譯後就可讀進該語言且進行分析。

若是沒有這類 parser generator 的工具,要做一個複雜的 parser 將會非常困難,且修改也很不容易。"complier-complier"意即 complier 某語言的規則,產生這個語言的 complier,像是 UNIX 裡的 yacc。不過 JavaCC 還有內含像是 lex 的 lexical analyzer 產生器的 功能。所以 JavaCC 可以看作是 Lex 加上 Yacc 的 Java 版。不過還是 有一些不同,Lex 和 yacc 是產生 C 的程式碼,而 JavaCC 產生的是 Java 的程式碼。Parser 的部分,Yacc 是 botton-up,JavaCC 是 top-down。

雖然 JavaCC 是用 top-down 的方式,但是它的 Lookahead 能力可以解 決大部分 top-down parsing 的問題。

JavaCC 是 Sreeni Viswanadha 和 Sriram Sankar 在 Sun 工作時 所寫的。現在 JavaCC 是 open source,由原作者繼續維護。且他們 也不斷地在加強它。我們可以從 https://javacc.dev.java.net/下 載到最新版的 JavaCC,含有原始碼、文件及一些範例。

4.3.2 Lexical analyzer

在 JavaCC 裡又叫做 token manager,token manager 讀進一串連 續的字元。依規則產生一個一個 token 出來。這裡的規則就是要解析 的語言中不可分離的最小單位。例如 C 語言裡的 “int" “main"

“(“ “void" “}" “;"等等,就是 C 語言的 token。當然 JavaCC 並不只限於解析 C 語言,只要我們能提供一組規則給 JavaCC。這一 組規則要以 regular expression 來表示。

(圖十三 Token Manager)

4.3.3 Parser

Parser 會讀進一連串的 token,分析她們的結構,作相對應的處 理,最後要產生什麼,可依程式設計者來決定。若只是要產生 syntax tree,可利用 JJTree 及 JTB 來完成,在以下我會做介紹。

程式設計者必須提供一組"Extended BNF production rules"

來描述文法規則,在每一個 production rule 之後,可寫入一段 Java 程式碼,來告訴 JavaCC 在符合此 production rule 時,要做什麼處 理動作,該產生什麼。JavaCC 最後會產生出一個負責的 parser 的 Java 類別,程式設計者就可以利用此類別來完成 parsing 的工作。

(圖十四 Parser)

4.3.4 JJTree 和 JTB

JJTree 是和 JavaCC 附在一起的一個程式,它是 JavaCC 的前置處 理器,可以幫助程式設計者產生 syntax tree 的結構,它會產生出可 以被 JavaCC 接受的格式,在每個 EBNF 之後加入新增 Node 的指令,

將每一個 production rule 都當作 Tree 裡的一個 Node,不需程式設 計者自己寫。只要將 JJTree 所產生的.jj 檔案在經過 JavaCC 產生 Java code,這些 Java code 再編譯後,就能將欲解析的語言 parse 結果輸出成 Tree 結構。JJTree 還會產生一個 Visitor 的 interface 以及每個 Node 的類別,程式設計者可以利用基本的 Visitor Design Pattern 進行 Tree 結構的 Tracing。

JTB(Java Tree Builder)可在

http://www.cs.purdue.edu/jtb/index.html 取得,做的事和 JJTree 差不多,不過它比 JJTree 還要多功能。

4.3.5 Composite Design Pattern

節錄自『Design Patterns 於 Java 語言上的實習應用 --- 結 城浩 著』一書。電腦的檔案系統裡,「檔案」要放在「目錄」﹝或叫 做「資料夾」﹞裡,而「目錄」也可以放在某個「目錄」裡。雖然檔 案和目錄是兩種不一樣的東西,但是兩者都是「可以放在目錄裡」的 東西。所以我們可以把它們視為同一種類。像這種「畫中有畫」的遞 迴結構,我們可以利用 Composite Pattern,

容器﹝目錄﹞和內容

﹝檔案﹞一視同仁,建立遞迴結構的 Design Pattern。以下是 Composite Pattern 的類別圖:

(圖十五 Composite Pattern 的類別圖)

以下說明出現的所有參與者:

• Leaf﹝葉子﹞參與者

表示「內容」的參與者,不能放入其他東西,如檔案結構的「檔 案」。

• Composite﹝複合體﹞參與者

表示「容器」的參與者,可放入 Leaf 參與者或 Composite 參與者,

如檔案結構的「目錄﹝資料夾﹞」。

• Component 參與者

對 Leaf 參與者和 Composite 參與者一視同仁的參與者。Compomemt 參與者是 Leaf 參與者和 Composite 參與者的共同父類別。

• Client﹝委託人﹞參與者 利用 Composite Pattern 的人。

Composite Pattern 範例

﹝放在和 Visitor Pattern 一起講解﹞

4.3.6 Visitor Design Pattern

若我們現在想對一個資料結構裡的所有元素做某項「處理」,這 個「處理」動作的程式碼應該放在哪裡。最直覺的相法是寫在表示資 料結構裡的類別裡,但是當我們的「處理」動作不只一個時,就需要 在類別裡寫很多的處理動作。而且若是我們想要新增某個處理時,不 得不修改原始的資料結構類別。Visitor Pattern 可以把資料結構和 處理兩者分開

另外寫一個表示在資料結構內穿梭來去的「訪客」類 別。當我們想增加新的處理動作時,只要再寫一個「訪客」類別就好 了。而資料結構這邊,要建立可以接受「訪客」呼叫的機制即可。以 下是 Visitor Pattern 的類別圖:

(圖十六 Visitor Pattern 的類別圖)

以下說明出現的所有參與者:

• Visitor﹝訪客﹞參與者

Vistor 參與者是對每個資料結構中的具體元素

﹝ConcreteAcceptor﹞宣告「已經找過 XXX」的 visit(XXX)方法。

visit(XXX)是處理 XXX 的方法,實際原始碼寫在 ConcretVisitor 裡。

• ConcreteVisitor﹝具體的訪客﹞參與者

ConcreteVisitor 參與者實作 Vistor 參與者。它必須實作每個 visit(XXX),敘述各個 ConcretAcceptor 參與者的處理。

• Acceptor﹝接受者﹞參與者

Acceptor 參與者是表示 Visitor 參與者的訪問對象。宣告接受訪 客的 accept 方法。Vistor 參與者則被傳遞給 accept 方法的引數。

• ConcreteAcceptor﹝具體的接受者﹞參與者 ConcreteAcceptor 參與者實作 Acceptor 參與者。

• ObjectStructure﹝物件結構﹞參與者

ObjectStructure 參與者是處理 Acceptor 參與者的集合的參與 者。讓 ConcreteVisitor 參與者有可處理所有 Acceptor 參與者的 方法。

4.3.7 範例

以下是本範例的類別與介面一覽表

名稱 說明

Visitor 表示訪問檔案或目錄的訪客之抽象類別

Acceptor 表示接受 Visitor 類別的物件個體的資料 結構之介面

ListVisitor Visitor 類別的子類別,列印檔案或目錄 總覽之類別

Entry File 和 Directory 的父類別的抽象類別

﹝有時作 Acceptor 介面﹞

File 表示檔案的類別

Directory 表示目錄的類別

FileTreatmentException 發生在對 File 進行 add 時的例外類別

Main 動作測試用的類別

(表十二 範例的類別)

以下是本範例的類別圖

(圖十七 程式範例的類別圖)

﹝完整程式碼部分請見『Design Patterns 於 Java 語言上的實習應 用 --- 結城浩 著』一書。﹞

因為這個範例所「Visit」的資料結構就是 Composite Pattern。

所以把它們放在一起說明,以下是兩個 Pattern 的各別說明:

Composite Pattern 的部分:

包括了 Entry 虛擬類別,File 類別,Directory 類別。File 類別 和 Directory 類別的父類別都是 Entry 虛擬類別。Directory 還可聚 合其他的 Entry 類別,也就是 Directory 可以放入 File 也可以放入 Directory 類別。這時,類別的操作就可以把 File 和 Directory 一 視同仁,例如雖然 Directory 中的 getSize( )方法

Size += entry.getSize( )這一行,呼叫 entry 的 getSize 類別,但 是實際上呼叫的是依照當時 entry 是參考到什麼類別,如果是 File 類別,則呼叫 File 類別的 getSize( )方法﹝單純傳回 size 欄位的 值﹞。若參考到的是 Directory 類別,則呼叫的是上方的程式碼﹝傳 回整個目錄的 size﹞。這裡我們同樣是呼叫 entry.getSize( ),一 視同仁的做法,就是 Composite Pattern 帶來的好處。

Public int getSize() { int size = 0;

Iterator it = dir.iterator();

While (it.hasNext()) {

Visitor Pattern 的部分:

光是看類別圖很難體會 Visitor Pattern,如果加上流程圖會更 好說明整個過程。

(圖十八 程式範例的流程圖)

此處理流程圖是假設在 1 個目錄下只有 2 個檔案。Main 對 Directory 的物件個體呼叫 accept 方法。Main 產生的 ListVisitor

此處理流程圖是假設在 1 個目錄下只有 2 個檔案。Main 對 Directory 的物件個體呼叫 accept 方法。Main 產生的 ListVisitor

在文檔中 軟體評估工具 (頁 29-0)

相關文件