:::

論文進度報告(2010/7/24):從Model到View

image

上週末終於把Model的部份寫完了,也就是說,PHP的部份告一段落,而接下來要進入JavaScript的部份。進度的概況大概就是完成上面那張圖中的右下角部分,而其他都還要繼續做。

類別 應完成 已完成 已完成百分比 程式語言
Model 100 100 100% PHP
View 73 0 0% JavaScript
Controller 9 0 0% PHP
總計 182 100 54.9%  

以程式數量來看進度的話,就是上面的表格。大概完成了一半,現在進入下半場:JavaScript。


Model完結之傷感

回顧一個月多前開始撰寫PHP的部分時,需要熟悉PHP物件導向、CodeIgniter、撰寫PHPDoc、單元測試的開發方法,讓我摸索了好一段時間。到現在Model完成了,單元測試也十分稱職地完成了他的工作,現在又要暫時把它擱在一旁,是覺得有點捨不得。

我在撰寫Model時,實際上撰寫的檔案數量為141個,細表如下:

類別 數量
Libriaries 107
Extension Libraries 4
Languages 1
Helpers 3
Unit Test 24
Views 2
總數 141

在開發過程中有不少重新思考UML架構的時候。如果繪製UML時能夠熟悉CI跟PHP的話,也許那時系統分析的數量會更為準確也說不定。

image

同時,這些程式全部通過單元測試。單元測試共34頁、456項測試。這是程式品質的一種保證。

而且我也把核心的工具整理成toolkit類別,包括Generic Object、Collection、Iterator等等,在未來開發PHP專案時又可以將之拿來使用,是非常寶貴的程式結晶。

雖然是這樣說,但到目前為止,仍然沒有什麼很令人亮眼的東西可以拿出來跟大家講。Meeting報告時看老師聽我講這些抽象的東西感覺像是有點無聊,我也沒有辦法orz

要看到實際上可以用的程式,還要把View跟Controller組合起來才有可能。再怎樣也是急不得的。


View開始之困惑:學習撰寫JavaScript

說要完結Model、開始撰寫View之後,已經過了一個禮拜了。老實說,到現在我還是很困惑,我到底該怎麼辦才好?跟一個多月以前寫PHP一樣,JavaScript是一個我很熟悉的程式語言,但是我一直沒有很正式地去學習它。說到JavaScript,一般會想到表單驗證啦、jQuery動畫特效啦,但是我要寫的層次是比這些都還複雜很多,是要靠一個指令,帶出整個標註工具,並且要由純JavaScript來跟伺服器溝通、交換資料。這種在別人網頁上進行從無到有的架構,對我來說是從未經歷過的高難度境界。

為了要將JavaScript嚴謹地架構起來,最近我開始學習更多相關技術:

JSDoc

JavaScript很自由,但是因為太過自由了,所以他的物件導向特性並不是很明確。JSDoc是類似JavaDoc的JavaScript專用程式註解格式,一個搭配JSDoc的JavaScript程式大概會長得如下列程式碼一樣:

/**
* 驗證是否為陣列
* @param $obj
* @return 驗證結果
* @type boolean
*/
jQuery.is_array = function ($obj)
{
    return (typeof($obj) == 'object' && ($obj instanceof Array));
};

我們可以利用JSDoc來說明一個類別的繼承(@extends)、建構子(@constructor)、方法的參數(@param)、回傳資料(@return)與型態(@type)、所需類別(@requires)等等在程式中難以說明的特性,而使得我所使用的IDE:NetBeans可以正確地解讀複雜的JavaScirpt程式。

image

如果NetBeans能夠正確地解讀,那麼就能在撰寫程式時即時地提供說明與自動完成的功能。

然而,JSDoc卻是一把雙面刃。由於JavaScript並不像PHP是在伺服器端執行,而是必須讓使用者下載到他的電腦才能執行。也就是說,JavaScript的註解撰寫越多,表示它的體積越大、越吃網路流量。為此,我還需要一種JavaScript的壓縮打包技術。

Packer JavaScript en PHP

常常使用複雜framework,如jQuery、jQuery UI的人,一定有碰觸過min打包版程式的經驗。研究JavaScript打包技術(Packer)的Dean Edwards已經將之發展到很成熟的地步,而且支援.NET、perl,以及PHP來使用。

讓我們來看看打包到底能做到什麼程度:以下左圖是原始程式碼,總共13649位元組;右圖是打包壓縮的結果,只有5177位元組。壓縮到一半左右的大小,實在是很棒的成果。

原始程式碼(13649) 打包壓縮結果(4691)
image  image

打包壓縮其實並不是什麼很神祕的技術,大致上可以分成普通壓縮與Base 64、是否縮短變數名稱等選項。普通壓縮中,他刪除了註解、多餘的空格、對齊(tab)、換行,並將程式撰寫簡化,以節省空間。除此之外,使用Base 62則能獲得更高壓縮率的作法,在edikud的blog中介紹了一些提高壓縮率的守則,但似乎是寫錯了,所以我更正之後說明如下:

  1. 區域變數名稱前加上_,像是function的參數。例如「obj」改寫成「_obj」。
  2. 全域變數名稱前加上$。例如「TYPE_ID」改成「$TYPE_ID」。
  3. 最後補充一項:程式每行結尾都要加上「;」。原本JavaScript會把沒有「;」的換行補上「;」作為宣告的結尾,但是打包之後,換行會被刪去,所以就必須在一開始撰寫時就養成良好習慣地加上「;」才行。

至於測試方法則不是我關注的重點,所以就不特別去在意。

搭配CodeIgniter的網頁快取功能,我就可以把打包壓縮過後的JavaScript以cache的方式保存起來,既能在程式有所更改時立即地轉換成打包格式,也不會重複進行打包動作導致系統資源浪費。

QUnit:JavaScript的單元測試
image

為了養成撰寫程式時的良好習慣,即使是寫JavaScript,我也採用Unit Test單元測試的開發方法。Qunit是一個JavaScript的單元測試工具,用法也十分簡單,介紹網頁裡面已經把主要用法說明完畢。

只是我並不喜歡原始QUnit的介面與功能,所以修改了不少版面、加入型態判斷、例外捕捉並顯示錯誤訊息等功能,建立一個屬於我自己好上手的QUnit工具。透過QUnit來偵錯,我發現我逐漸改變以往使用alert來偵錯的方式,QUnit不僅能詳細地回報錯誤細節,速度與效率快上許多,因此更方便於跨瀏覽器之間的測試。

等待我把QUnit使用更熟悉之後,我會再把改良版的功能發佈出來跟大家共享。

JSONP:跨網域AJAX技術

以往在寫DSpace時,我是使用了很多AJAX技術,但那都是同一個網域底下的資料存取,而我的論文則是往更高的目標邁進:跨網域AJAX存取。

JSONP是一個天才想出來的非正式方案。這是利用<script>標籤的src載入JavaScript可以讀取不同網域的JavaScript檔的特性,只要在src的網址中以GET方式輸入參數,然後伺服器則回應相對應的資料並以JSON的方式讓使用者端的瀏覽器去做callback回呼的動作,就能夠達到跨網域AJAX的境界。詳細的作法可以先看看Hpyer的介紹

這個是很簡單的作法,但也是很危險的一種技術。因為參數以GET的方式傳遞,也就是說資料都會是以明碼來顯示,這就是一種容易被入侵的漏洞。對此我在思考利用公鑰私鑰的方式來為傳遞參數進行加密的作法,不過似乎是挺複雜的,我現在連基本的JavaScript物件導向都還沒熟悉呢。

此外,JSONP是以GET方式傳遞參數,而CodeIgniter又剛好最討厭GET傳遞參數。調整CodeIgniter讓他能支援JSONP,讓我花了不少功夫。等我真的把它馴服了,我們再來談談CodeIgniter的調整方法吧。

NetBeans對於JavaScript支援沒這麼強

習慣NetBeans對於PHP的支援之後,改寫JavaScript時就會明顯地感覺到不方便。這個不方便其實比起什麼功能都沒有的筆記本,或是只有語法顏色標示的編輯器來說還是強的很多。NetBeans提供了方法的自動完成(搭配JSDoc就如上述效果般)、可能錯誤的提示、自動補完()、{}、[]等括弧。

雖然不錯用,但跟PHP的支援比起來,少了兩個對我來說還蠻決定性的功能:

  1. 缺少變數名稱自動完成:也就是NetBeans無法取得JavaScript的變數前幾個字來猜出後面的字,這讓我寫function函數的時候就很不習慣,沒辦法快速帶出參數名稱。
  2. 方法自動完成的速度慢:要使用方法的自動完成,必須要在變數撰寫完畢之後加一個「.」以表示要使用方法時才會帶出來,但是選單速度非常慢,大概要等到1秒才完成,而且一旦自動完成輸入錯誤而想要回頭修改時,又必須要回到輸入「.」的情況才能再次帶出自動完成選單。非常地考驗耐心。

因此我正在找尋是否有NetBeans的Plugins能夠補強這兩個缺點,不然其他都很完美了說。


寫好系統只是興趣,並不代表研究順利

身為一個社會科學領域(表面上是文科)的研究生,我很瞭解理工科那種想把系統做好就算是完成論文研究的作法在這邊是行不通的。社會科學的研究講求結果分析能力,在好的環境中分析好的結果,在壞的環境下也可以分析出壞的原因,換句話說,不管研究對象的環境是好是壞,研究都能夠進行。

但是,其實我並不喜歡這種調調。並不是說這樣好或不好的問題,只是我個人看到問題擺在那邊,就會想要去動手解決,然後找出更好的方法之後,跟別人說明這些作法。就像我在這個Blog作的事情一樣,我的論文也是一樣的理念。

所以我不是用別人寫好但我並不滿意的系統,而是自我挑戰作一個系統,不僅只是作,而是以對我來說前所未有的嚴謹態度來撰寫一個系統。基於毛老師的理論,我今天用這種方式撰寫系統,以後我也應該會繼續用這種嚴謹的態度面對未來的工作,而這也是我的自我期許之一。

然而回到頭來,我很清楚這種想法至多仍只是能稱得上是一種興趣,而與研究進度無關。撰寫好系統,並不代表實驗能進行順利、問卷會設計、統計會分析,這些技術與知識都是不太相關的事情,而我則是抱著來一個我學一個的心態,一步一步慢慢地做完這個論文而已。

有些人也許看著我三不五時刻著系統進度,就以為我論文快完成了,但事實上兩者是不太有相關。那為什麼我要花這麼多時間在做系統呢?我會回答說這是一種興趣,更直接一點,我依然在耍任性,就跟寫書的時候一樣。

這種個性,真的是沒救啦。