:::

論文進度報告(2010/10/10):幾乎完成工具列

image

上次的進度報告之後又隔了兩個多禮拜,最近也是一直在研究JavaScript的基礎技術,然後一邊在Blog把整理好的東西寫出來,希望能給一同鑽研JavaScript的程式設計師作為參考。評估各種寫作方式並訂定之後,就是繼續兩個禮拜之前停頓的進度,而繼續把工具列的部分完成。現在工具列只差「通知」功能尚未實作,但這是要等標註功能實作之後才會有通知,接著才是繼續完成這部份的功能。接下來就是要整理標註功能的UML了呢,又是一項大工程。在這之前,先來整理目前的論文進度吧。

目前的WebApp端的進度

元件 預估程式數量 已完成 UML類別圖
toolkit 17 17 1
core 15 13 1
kals_window 6 6 1
kals_toolbar 30 24 2
kals_text 38+? 0 3
search 6+? 0 1
統計 112+? 60 (53.5%) 9

整體來看,目前完成了大約一半的程式。由於使用物件導向架構開發,每個細節元件都是取用於toolkit或core中的上層元件,在開發同時也會不斷地改良這些元件,因此系統開發的速度會越寫越快。當然,這只是理論上而已。

也許會有人注意到類別程式的數量跟之前比起來有所減少,從之前的114降低到了112。我嘗試簡化系統的功能跟開發的方式來讓整個專案能更快完成,目前是將「自訂外觀」、「個人相片」的功能取消,暫緩適應小螢幕的功能調整(toolkit設計時有考慮小螢幕,但不一定每個功能都能適用就是);而開發中也只對關鍵功能設計單元測試,並且緊對Firefox進行測試,Chrome、IE、Android則在未來有機會時再進行統一的檢查。

navigation

上圖是kals_toolbar中navigation的UML類別圖,這是工具列上各個視窗的功能設定。其中灰字的類別則是暫停開發的類別。詳細的UML類別圖,請參考KALS Wiki

至於專案時程仍暫時維持在19天後完成,也就是10月29日。能不能完成我也沒把握,只能說盡力而為而已。

一改再改的JavaScript物件導向繼承寫作方式

一開始我的JavaScript是用最原始的prototype繼承法,但是由於這種方式在使用上會有些問題,而且我需要使用上層類別的方法,所以又花了一段時間回頭找尋相關資料學習。

首先學習到的是call跟apply的用法,但是發現到JavaScript仍有傳址問題存在,所以又把所有的屬性與方法寫在類別的建構子裡面,不過那將會造成系統資源大量消耗的問題,不得不再找尋新的方法。

接著找到的是Dean Edwards的Base繼承類別,他的確是很好用,寫法簡潔明瞭、又有呼叫上層類別方法的this.base()可使用,但是我使用的Aptana Studio看不懂,而我另外又試用了五六種JavaScript IDE,一樣是看不懂。儘管我後來找到讓Aptana Studio能夠理解的Base繼承法,但是最後仍毅然決然地使用最原始的prototype繼承法。

這是因為我在找尋這些方法的期間,學習到了prototype利用call、或是經典的base方法來呼叫上層或甚至是其他類別的方法來繼承並覆寫,讓prototype的寫法有了更多彈性,而能夠滿足系統的需求。儘管寫起來是比Base繼承法繁雜許多,但是由於prototype繼承法容易分析,許多JavaScript IDE都能理解,也是JavaScript程式設計師應該要知道的基本功課,這是我最後選用prototype繼承法來開發的原因。

這段期間不僅是一直翻閱相關資料、測試方法的優劣,還把系統的所有程式改寫了三次之多,著實非常地花時間,但也因此學到了不少東西。

重新檢視單元測試的必要性

core

在撰寫toolkit跟core的時候,我會要求自己盡量撰寫單元測試,並且最好是能夠測試到所以功能,也就是要求高「測試覆蓋率(Code coverage)」。上圖是core的UML類別圖,其中橘色的小註解標示著這部份的系統有設計單元測試的意思。小小的15個類別裡面,就有7個單元測試,力求核心元件要穩定。

過於繁雜的單元測試

上述在核心的工具時還可以做,到後面設計UI時,設計單元測試就越來越麻煩。我是用setTimeout來設計成機器人的方式,利用jQuery去選擇物件來點選元件或輸入資料,用以測試功能是否正常運作。但是這個機器人也常常做出一般人沒辦法做到的功能,導致測試的水準是比實際上更為高。舉例來說,原本使用者不可能點到某些隱藏起來的按鈕,可是用jQuery去點就可以點到、使用者必須等待視窗關閉並開啟之後才能執行下一個動作,可是jQuery就是無視視窗開閉來進行動作,導致他找不到下一個視窗的功能。也許是我設計單元測試的方法不對,但目前這樣做的確是很累,也顯得不切實際。

總結以上,簡單來說有兩個問題:

  1. 設計單元測試比設計元件本身還花時間,頗有本末倒置的情況發生。
  2. 單元測試不見得切合真實手動操作的情況。畢竟UI設計不像之前的計算用或存取用的程式這麼單純。

因此有必要重新檢討單元測試的必要性。

選擇重要的功能設計單元測試

仔細想一想,不需要全部功能都進行單元測試,去拼那個「測試覆蓋率」實在是很浪費時間與精力,只需要針對重要的功能設計單元測試即可。具體來說,針對具有以下兩種條件的功能來設計單元測試最為實用:

  1. 關鍵功能:千萬不能出錯的功能,當然要用單元測試確保他的正確性。
  2. 多道手續:與其說是在意其正確性,不如說是檢查時因為手續太多很麻煩,不如設計成單元測試的機器人讓他自己跑出的目標功能,再看看哪裡有問題,可以省下許多手動操作的時間。

也就是說,即使很重要的功能,但是如果很簡單就可以手動進行測試,或是其他測試中已經會使用到的功能,那麼就不需要刻意地撰寫單元測試。

程式要經過測試才算是完成。我仍然堅持這個最低底線,但現在並不強求一定要設計成自動的單元測試,即使是手動測試也可以算是勉強及格。

缺乏多人合作的遺憾

寫著寫著來講一個額外的小故事。

有天晚上回到宿舍的時候,發現室友學弟的位置旁坐著另一位學生。

學弟是資科所的學生,研究題目是跟雲端相關,當然也是寫程式的工作。看起來他應該是跟他同學兩個人正在趕一個系統,我偷偷地瞄到了phpMyAdmin的介面,兩台Mac筆電外加一個外接螢幕通通擺在桌上,旁邊還有喝到一半的五十嵐珍奶,看來晚上是要熬夜拼進度了。

老實說,我很少與人一起分工合作地寫程式。教人寫程式的經驗很多,但是可以像學弟他們那樣,「那個帳號登入的部份就拜託你了。」「OK!」地將一個系統分成幾個部分、再各自完成的經驗則是相當地少。不過架伺服器的各功能分工倒是有的,教育部計畫的時候,但那畢竟是功能調整,不太像是寫程式的這種「創作」。

我知道這種分工合作經驗的重要性對於程式開發來說並不亞於技術知識,大型的、有價值的系統是無法、也沒有時間讓我自己一個人完成,而我知道這正是我的弱點。至今我仍然是一個人在寫著程式,就像是現在正在做的碩士論文一樣。

儘管如此,我也在學著讓自己的程式「更好讀」、「更容易讓人使用」。像是建立嚴謹的物件導向架構程式讓人方便使用、遵守PHPDoc、JSDoc、cssdoc這種具有標準規範的註解讓人容易閱讀、利用UML跟網站草圖讓人理解整個系統,使用甘特圖與Wiki共筆工具來模擬多人合作時的專案互動。

我希望我能夠有資格與未來的夥伴一起合作開發一個大型的系統,所以我要加油,嗯。

結語

現在最令人擔心的是,19天後到底能不能完成系統呢?即使系統完成,後面還有好多後續的動作要做,多到讓人現在不想要面對的事情。能在這學期畢業嗎?能在明年3月之前如期把論文交給國中圖嗎?問題實在是太多了。現在還會有人問我要不要繼續念書,還是去當兵,還是要去當資訊替代役,但是現在能不能畢業都不知道啊XD

總之,每天都努力地繼續寫程式、寫Blog記錄,努力地向前進吧。

題外話,國慶日當天寫進度報告真是格外值得紀念?