2007年11月30日 星期五

H01 Controller控制系統物件,Process控制專案產出

還記得Data Model與View吧?它們都接受Controller的支配,何時該提供值與該設定值,都要看Controller裡如何定義。同樣的道理再往上一層,我們把全部的需求與程式都視為系統必需物件的話,那麼這些物件該在何時出現,何時提供給其他文件參考則都視Process如何定義。

CMMI是一個定義Process的標準。參考著許多開發系統的專案,專案們得到許多經驗值去明訂從什麼文件經過什麼動作之後可以導出下一份文件,專案依此一步一步地往前演進,也獲得許多按照步驟應該出現的產出,不管是程式還是文件,直到完成驗收出了版本總算把專案結束掉。而Process則是在專案完全停止前,規定要用什麼樣的順序來做與專案有關的動作。

即使系統已通過驗收,但沒人敢保證不會再發現錯誤或者使用不會再添加原來沒有的功能;所以維護同樣也是接受Process所管理的動作,以確保在應該有所動作時做應該做的事情。

2007年11月29日 星期四

G26 建立第一版的同時建構維護基準

終於,忙碌許久的系統終於要出第一個正式版本了。收集的需求、功能規格書、Data Model、系統硬體架構、設計規格書、元件規格書、實作的程式、測試程式、測試報告、API參考文件、系統安裝手冊、系統使用文件、系統開發教學文件……等等所有與系統有關的物品,全部都要在剛出完版本的那一刻進入建構管理。

為什麼要建構管理?首先當然是讓日後使用的人明白與現在版本相關的一切都在這個建構之中,取出的任何物品都是正確的版本。以前公司的專案曾經發生過負責人員沒有把專案最後版本的程式碼放回公司伺服器,使得後來去維護的人在找不到從哪個版本去改的狀況下,從程式反推需求後再寫出對應的程式。原先十分鐘可以改好的問題後來花了整整兩天在處理。當然,那個歹命的人又是我。

千萬要記得,系統每出一個版本,與當時系統有關的所有程式與文件也要建立一個對應的建構的版本,這是最基本的觀念。但是不要以為依版本收集妥當就沒事,同時還必須要建立現在版本與上一個版本之間的全部差異!

2007年11月28日 星期三

G25 追溯關係(5)──System vs Document


一直認為每一個動作都會有它必須要做的來由,動作會有它的產出,也會有它的影響。基於系統的功能目的,會有對應要有的程式,接著有對應來保證程式運作正常的測試程式,有對應程式開發的API參考文件,也有教使用者使用的說明文件。

文件與系統的對應追溯差不多就是如此。系統上的每一個物件都有它所對應的功能規格,也有它所對應的使用文件,不管是程式、元件、設定檔或是訊息檔,裡面的每一個小項目都有其應該對應的來龍去脈。

很明白地,需求、設計、程式、測試、文件、使用是一脈相承的連續產出,有前面的需求才會有後面一系統物件的存在;唯有記錄其中的關係方能明確地知道動了其中一個部分的時候,同時會有哪些東西需要跟著修改。只要忘了或懶得建立其中一項關聯,那麼在需要知道追溯關係的時候就難以再分析求得。

2007年11月27日 星期二

G24 英文字典vs英文課程──API Reference vs Tutorial

當我們開發好系統後,要如何讓其他原先不懂的人明白如何使用系統內部的程式來做出想要達成的動作呢?最理想的方式莫過於使用Tutorial循序漸進地來引領大家慢慢瞭解系統的內部。

公司的產品剛做出來時,提供給相關的專案作客製化時,專案人員抱怨說新的產品不知道要怎麼用,不清楚有哪些API。的確,產品剛出第一個版本時的說明文件少得可憐,做出來的說明文件坦白說實在有點不知所云,連我看了都不懂裡面的狀況,更何況資歷更淺的人呢?

有人提議說把教學文件做好一點就夠,但是我堅持應該要有系統所有的API參考文件。Tutorial就像是課本,會說明其他人所希望知道的系統,可是教學不可能教全部的東西,應該另外有一份所有東西的參考資料存在;就像英文字典會收集世界上所有的英文單字,而我們的英文課本只會選擇出英文字典裡最基本,最需要學會的一些單字來教學。

API Reference與功能清單很類似,後者是列出系統全部可以做到的事,前者則是列出系統內部可以使用的Class與方法;相同的是兩者都需要記錄才有可能寫出內容,這是直接把想法寫成程式的作法難以做到的。

2007年11月26日 星期一

G23 驗收的文件(11)──系統開發教學

一般只提供使用的系統,交付安裝手冊與使用手冊後就可以過關。但是系統如果要交給客戶自己維護,甚至自行在系統上開發新功能時,那就得再交付一堆下述的文件才能過關。

首先要有開發環境的安裝手冊,包括開發伺服器的安裝、開發工作站的安裝,同時應該會需要安裝同步開發時控管的軟體。接下來要開發使用的工具軟體清單、安裝手冊與使用手冊,再來是如何建立原始程式工作區,如何使用同步控管軟體;以及前面提到的系統API參考手冊。

前面這一堆都還只是準備動作的文件而已,開發的重頭戲在於要怎麼教會使用者系統的精神、架構的意義,接著是一步一步地帶領使用者由淺入深地慢慢懂得如何使用API來組合成他們想要做的動作。之前為我維護的系統撰寫這一部分時,光是最上層開發或維護Use Case花了五天才寫出細節不夠完整的教學文件,講授時則是用了三天才講完較基礎的部分。

每一件想做的事物都必須投下相對的人力與時間,在此又是一個有力的印證。

2007年11月25日 星期日

G22 驗收的文件(10)──系統使用手冊

將所有的電腦都安裝妥當後,接下來要教客戶怎麼使用系統的功能。設定、起動與結束是最基礎的幾個功能。

使用手冊大致上依照Use Case包含的Activity Diagram裡的User那塊swim lane的動作依序講解下來,在需要操作系統的時候貼上一張圖顯示要在哪裡輸入些什麼,系統有回應時解釋各種不同的反應代表什麼意義,接下來要怎麼做等等。原則上依每個Activity以一個步驟來講解為宜。

如果系統有明顯的子系統區分時,要編排不同的使用手冊。例如系統含有使用者管理與管理者監看系統狀態等等的功能時,由於使用者角色的不同,這些都應分開為每一種角色的使用者撰寫一份使用手冊。可以考慮由測試人員在Test Case測試時,把結果正確的測試步驟一一轉出為使用文件的內容並擷取對應的系統畫面。

每一份使用手冊也需要針對其範圍另外編寫系統的可執行功能清單、可用參數列表、錯誤訊息清單、詞彙表等等的章節作為參考。這部分應可在設計文件中得到並附加在使用手冊後面。

2007年11月24日 星期六

G21 驗收的文件(9)──系統安裝手冊

根據硬體架構與設計文件可以知道系統有哪幾類的電腦,每一類電腦的硬體規格、應該接續哪些週邊、使用什麼作業系統、安裝哪些軟體、需要哪些程式執行檔等等。系統安裝手冊就是循序漸進地帶領使用者建置起各個角色的電腦設備。

安裝手冊的編排要按照先後次序,內容則要巨細靡遺地說明每一個步驟,附上執行該步驟時的畫面圖檔或是擷取安裝時的動作影片都是讓使用者更能明白安裝操作的理想方式。製作安裝手冊的人通常會拿一台符合規定的乾淨電腦,按照規定從無到有地依序安裝並且設定,同時將所有過程按部就班地記錄成安裝手冊。安裝手冊裡每完成一項軟硬體的安裝與設定後,應該說明如何驗證該項軟硬體已經正常安裝的動作以便確認。

如果系統需要交給客戶使用開發環境,那麼安裝開發環境也需要另外製作出一份安裝文件。總之,每一種用途的電腦都該有一份專用的安裝文件。

2007年11月23日 星期五

G20 驗收的文件(8)──系統測試報告

關於系統的每一種測試的時間與結果報告,都應該彙總起來在驗時交付的。

系統程式碼的Unit Test會與原始程式一起交付,在開發環境裡隨時可以執行驗證正確性。這方面的報告只要填寫何時跑過全部的Unit Test且沒有任何錯誤即可。

與Use Case有關的Test Case應被追溯,測試時開立的問題單都會註明屬於哪一個Use Case,修正後再用該Use Case的所有Test Case重測一次。

對於系統來說,每隔一段時間就應跑出一份報表,記錄各個Use Case至今總共測出了幾個問題、修正了幾個、修正的百分比多少,這些數字也會被加總在子系統層級與整個系統層級來表現。測試階段時每隔一段時間就要跑出一份這樣的測試報告,所有的報告都應交付並建檔管理。

2007年11月22日 星期四

G19 驗收的文件(7)──API參考文件

在OOAD開發流程下,在每個Class、每個方法與每個屬性被設計出來的時候,應該都已經有它應該存在的原因與其對應要去處理的動作。在Java的開發環境裡,幾乎只要使用Java Doc把所有程式碼的註解跑過一遍就可以擁有完整的API文件了。

在Component的情形下,除了基本的註解顯示的內容,應再附上Properties使用的名稱與其影響的功能,以及在各種不同的例外狀況下傳回Exception裡的所有傳回狀況代號;如果有使用到任何外部檔案的時候,也要包含檔案格式的說明。當然這些在元件設計的時候都應該同時有追溯表才是。

在把方法視為函數呼叫的類別裡,最重要的是詳細說明每一個方法的呼叫方法與作用,最好是能附上幾個使用範例。這些內容的寫法可以參考JDK的API文件寫法。

對開發與維護的人員來說,API參考文件就有如系統的開發API字典一樣,要包含系統層次裡所有可能會使用到的Class、方法與屬性說明。

2007年11月21日 星期三

G18 從程式倒回Design Model的問題

身邊偏好將想法直接變為程式的人常說,程式裡隱含可正常執行的Model,如果需要UML圖的話就從程式碼倒回來,保證可以拿到最新最正確的。

這句話原則上沒有錯,無論是Class Diagram或Sequence Diagram都是系統真正在執行的。但是令人困擾的是倒回來的Model是一大包什麼都有的產出,我們不容易從裡面找到我們所需要的條理,也不容易正確地分辨系統的層次。更要命的是,要是設計者只是為了功能而實作,倒回來的東西可像極了混成一大團的毛線球。

試過用IBM RSA把維護系統的程式碼倒回Sequence Diagram,得到的結果實在很長,一個特定方法之下所有呼叫順序全部都列出來。由於該方法原先就沒寫好,有些邏輯在上層,有些則放置在更下面的邏輯裡,完成不知道原先設計者思考的是什麼;後來只好去問原來的設計者,得到的答案竟然是:我忘了,你可以先看程式碼後再問看不懂的地方嗎?當然我就丟下不看了。

設計的層次本來就有問題時,怎麼倒回Design Model都是沒有用的,頂多貼到交付文件裡騙騙那些什麼都不懂的使用者。建議還是先用Model設計,確保各個層次與物件負責範圍,以免系統最後變成一團大毛線球。

2007年11月20日 星期二

G17 程式設計的能力(5)──取得狀況、判斷資訊與執行動作

做事與寫程式的理念實在太接近了,因為二者的在細節上的處理同樣都是取得狀況、判斷資訊與執行動作。

做事情是為了達到目的,但並不是一味地往前直衝而已,而是需要判斷現在的局勢然後決定一個最適合的作法,執行作法後還要再檢查結果與影響並進行再下一步的動作。程式設計也是如此,我們可能設計直接執行一個動作,或者先取得系統裡某些地方的資訊,加以判斷狀況後執行不同的動作,當然也會根據執行後的結果來取決接下來要做些什麼。

開發系統的時候,在商業邏輯的處理時主要著重於配置物件、定義動作與要處理的資料這類的思維;再詳細設計商業動作內部的分解行為時,則是以取得狀況、判斷資訊與執行動作這樣的想法來逐步堆疊出達成方法目的的內容。

2007年11月19日 星期一

G16 驗收的文件(6)──系統原始程式

這部份應該比較沒有問題,再怎麼樣都只要把專案裡用到的所有程式碼,一股腦地壓成光碟直接丟給客戶存查就鐵定沒錯。不過在一般的專案裡由於沒有控管與追溯,裡頭大多都帶著一堆雜七雜八沒用的程式,也沒有人敢任意拿掉什麼,因為就怕拿了一個Class後讓系統再也跑不起來。

以架構與元件設計的產出為基礎,分門別類地把Package放到所屬的資料夾。在每一個Package與每一個Class的產生都能找出原因,且能找出誰在使用時,在專案裡要出現多餘無用的程式是很不容易的;只是要有這樣的效果,都是必須投入時間從頭開始分析、設計並記錄才能享有的。

測試用的程式最好也在原始程式的交付範圍,因為要驗證原始程式執行時的正確與否,使用曾經使用的測試程式是最快的;同時也可以檢查測試程式裡寫入的測試範圍有哪些,而且可隨時加上新的測試內容來驗證原始程式。

2007年11月18日 星期日

G15 程式設計的能力(4)──配置物件、定義動作與輸出入資料

當我們可以正確地拆解動作與物件,同時也瞭解異中求同、同中求異的概念後,接下來要做的就是把拆解下來的各種不同的“零件”依概念組合成系統需要的Design Model。這時候還需要參考的設計理論是Design Principle與Design Pattern。

物件的放置與群組化的處理可以根據Design Principle,像是OCP(開閉原則)、DRY(勿自我重複原則)、SRP(單一責任原則)、和LSP(Liskov替代原則)等OO設計原則,期望產生可擴展、可重覆使用、且好維護的系統。在需要達到特定的需求且避免可能的問題時,則套用Design Pattern的設計來塑造具有彈性的局部設計。

接下來就按照物件分析出來的關係,根據動作的先後一一在對應的物件上加上適當的方法;在此同時將傳入的參數、傳回的結果與拋出的例外一併宣告。如果設計的是元件,則建議將可能會有多形使用的方法一併加上,以減少未來變動時再度產生改變的影響。

系統再怎麼做幾乎都能滿足客戶的需求,但是系統要能有彈性、易變動、好維護之類的特性,就全仰賴設計者有多少能力了。

2007年11月17日 星期六

G14 元件切割大小的抉擇

元件在定義時就需要花上功夫。由上而下設計時,開出的方法包含的範圍是比較大的,屬於Controller裡的一個特定動作;但實作時我們會發現許多真正要實行的動作是更加細微的;這之間的落差該怎麼辦?

我們當然可以只用一個方法來含括符合Controller動作裡想要做的事,這樣一來在Controller上簡單易懂;只是在Component實作時會在裡面處理較多的邏輯與動作。元件寫得越大,內部邏輯包含得越多,也越加讓這個元件只能符合部分的需求。

為了讓元件符合重用並滿足更多樣化的需求,我們也可以讓元件控制的範圍最小化,如此一來就有機會任意組裝順序以滿足不同種類的動作需求。但是元件寫得越小,就得加寫上層的控制動作,使得Controller的管理變得煩瑣。

我的解決方案是使用複合型的元件。需要直接使用底層控制元件時,就用最小單位的Component;在較多邏輯的情況時,就在原先的元件外再多包裝一個大的元件,讓原來的元件只是大元件內部的Action,邏輯就集中在大元件的Component Controller來做。如此一來就能依想使用的範圍選擇適合的元件。

2007年11月16日 星期五

G13 驗收的文件(5)──細部設計相關文件

如果執行的步驟是經過設計一段程式碼,那麼通常會獨立成一個方法。這時需要方法的宣告規格,然後是裡面所做的流程與各個步驟執行了些什麼。

如果執行的步驟經過設計是獨立一個元件來負責處理,那麼我們會先定義出Component Interface的規格,再依照Component Interface的定義在一個(或數個)Package裡設計出一些Class來完成Component的應有規格。

以細部設計裡所提到的想法,靜態部分會有實作Class與Component Controller、Component Action兩層,另外還有Properties的定義以及Component Exception;動態部分則應該要有每一個介面方法在執行時的順序。依此可以得到Component的Class Diagram與Sequence Diagram。

別忘了架構設計時使用的元件方法追溯是維護時很重要的一份文件。

2007年11月15日 星期四

G12 程式設計的能力(3)──異中求同,同中求異

在多個不同的地方找出共同的部份抽取出來,在抽取出來的共同部分裡又能分辨出差異的地方。聽起來有些玄妙,但是這卻是要做好設計不可或缺的能力。

從物件角度,系統每個物件都是各自獨立的物體,我們必須去分析物件間的共同關係,將之抽取為Interface,在處理Interface時又必須可以分辨出它的實體是哪一種物件。

從程式角度,某一段程式碼在多個地方出現,因此我們會將之獨立成一個子方法供需要的時候呼叫,但是在子方法裡要能知道是從哪裡呼叫來的。

從系統角度,每個Use Case都被設計為一個View對應一個Controller彼此是沒有交集的,此時會在所有的View進入Controller之前加上一個Façade作為共同經過的處理,在Façade裡必須知道現在進入的是哪一個Use Case。

共同的部分是要作為reuse使用的,差異的部分則是用來區分每個物件、程式或Use Case的唯一性。找出同理與區分差異的動作做多了,現在幾乎隨時隨地都在對身邊的所有對話與事件作推理,這應該屬於職業病的一種吧?

2007年11月14日 星期三

G11 做人的方法(6)──明白自己的定位

在系統裡處理事情的單位有Controller與Action,對應到現實生活上同樣也有管理者與執行者的角色。管理者負責決定事情應該有哪些動作並控制現在執行的狀況,執行者則負責執行特定的動作並向管理者回報執行的結果與無法處理的狀況。

人在參與事情時應明白自己的角色:管理者決定好動作並分派給適當的執行者去做,隨時蒐集各個執行者的狀況並參考調整接下來的動作與時間點;執行者只需要努力在限制時間內做好指派的工作,在有結果或是應由管理者決定的例殊狀況時立即向管理者回報。管理者若管得太細會有失焦的可能,執行者若把管理者該作的決策自己決定掉了則會有失控的狀況。

開車在路上時,對於車子而言我們是管理者,但是對於後面的車來說我們卻是執行者。開車時,我們要不斷地接收路況、車況等等的資訊來決定要如何駕馭車輛;另一方面我們又必須使用燈號讓其他車輛明白我們接下來會不會有加減速、轉彎等動作,好讓其他開車的人控制他們的車作好配合的準備。應該可以想像車禍的發生大多是駕駛無法控制好自己的車,或者其他車子沒有告知接下來的轉變而來不及反應。

人應該明白自己當下所處的位置與應該做到的責任,才比較不會搞砸事情。

2007年11月13日 星期二

G10 驗收的文件(4)──架構設計相關文件

在架構設計的那些文章裡,根據MVC的原則畫分了系統的各個層次。架構的層次可以依照實際的狀況調整,比如像上一節的Web-Presentation-Business-Integration-Resource就被分為五個層次。

每個層次如果應用了一些Design Pattern或者是打算設計為Framework,那麼為了形成系統的架構,就必須先有形成系統框架的程式;這當中也包含了各個層次或硬體之間資料傳遞所必須的橋樑設計。如果有這樣的設計,在這部分就應該先有框架的功能規格,裡頭應包含Class Diagram、Component Diagram與Sequence Diagram。

每個Use Case依功能規格書,以符合框架設計為前提被設計成一堆Class,Class裡依步驟的解析會有使用到Component的動作。在Use Case Realization裡記錄的時候向下只需記錄到使用Component Interface的哪個方法即可,主要記錄的內容著重在陳述Use Case裡的各個步驟與遇到的各個狀況要如何處理。這部分的文件應包含Class Diagram、Sequence Diagram及其他視需要而畫的UML Diagram。

請記得這時雖然還沒有牽涉到Component的內部,但需要記錄使用哪些Component以及使用了什麼方法。

2007年11月12日 星期一

G09 驗收的文件(3)──硬體架構相關文件

系統的程式要佈署到Client與Server上時,有些人的作法是在每一部執行的電腦上放置一份所有的程式,那麼不管在哪一部電腦“肯定”都可以正常執行。

當然以使用者的角度來看只要系統正常運作,其他都是次要的問題,可是一部電腦裡明明放了一大堆根本用不到的東西,卻又無法明確指出哪些是必要的,哪些根本用不著會不會太浪費資源了些?如果放置物品的地方是你的房間、你的車或你的床,你會容許把一大堆有的沒的全堆在裡頭嗎?

隨時隨地建立關聯的追溯是可以立即追蹤出指定的物件是否必要的最快方式。從Usc Case、Library、Framework、Component、Class一路追溯而下,所有物件應該在什麼地方出現並被使用都可以知道它為什麼要存在。

下圖來自Sun OO-226課本第15章的Tier and Layer Diagram,是個不錯的範本。硬體架構的決定將會影響再上一層的架構設計,並會由此導出安裝手冊的內容。

2007年11月11日 星期日

G08 程式設計的能力(2)──能夠拆解物件

程式設計的另一個能力是物件組織能力。能夠準確無誤地從一堆雜亂的名詞挑出適合作為Class與應該是其對應屬性,並分析出所有Class之間的參照關係,是建立Data Model的重要基礎。這個能力其實不難培養,通常有兩個方向可以思考。

一種是觀察靜態物件的組成。生活裡有很多實際的物品,每件獨立的物品我們都可以仔細觀察它擁有了什麼特性:像是顏色、尺寸、形狀等靜態描述,或者是動力、移動方式、跳躍等動態描述,這些都屬於物品的特性。還有物品是否使用了其他的子物品?像是汽車裝的輪胎就可以視為子物品而存在,這樣擁有的關係也需要記錄在物件裡頭。

另一種是動態關係的組成。在拆解目的時我們會得到許多工作步驟,精確地把每一個工作步驟指派到應該執行它的靜態物件,就是最終的目標。要往這個方向邁進,我們必須清楚的知道每個靜態物件的責任,才能判斷出該由誰來負責。這同樣是日常生活與工作上時常會遇到的情境。

我們並不能保證每個人想的分類都會是正確的,因此需要review的機制來驗證每個人的想法並加以調整。

2007年11月10日 星期六

G07 驗收的文件(2)──Data Model相關文件

系統所要處理的是資料,資料在系統裡面不會漫無目的地到處亂放以免增加存取的難度,因此我們會將輸入輸出用的資料,依用途與關聯分門別類地建立盛裝的Data Model。

Data Model裡的Class名稱與內部的屬性應該都可以在系統詞彙表裡面找到並定義其關聯。Data Model是很重要的設計,由於這是最底層被使用的模組,所以必須要求物件之間的關係,不管是擁有或是使用關係,都必須是正確的。一旦後來發現錯誤調整了關係,那麼會連帶地影響所有使用到變更部分的程式內容,影響是十分龐大的。

Data Model文件主要要表達的是一共有哪些資料物件,內部包含了哪些屬性,以及與其他資料物件之間的從屬及使用關係。可以選擇用Class Diagram表達,也可以選用ER Model來表達這些內容。資料實際儲存的格式也要同時記錄下來,不管是XML的格式或是資料庫的語法。

2007年11月9日 星期五

G06 程式設計的能力(1)──能夠拆解動作

系統被拆解為功能,功能拆解出步驟,步驟中決定做的動作,每個步驟與功能都預先想好可能會發生的例外狀況,並決定好萬一發生了該怎麼處理。雖然會有資深的人幫我們準備好所有的資料,但是這卻是我們應該培養出來的能力。

上級交待一件事情,在確定目的後就應該要去分析這個目的可以拆解為哪些相關卻不重複的工作項目;工作項目確定後,要再去想可以分解為哪些獨立的工作步驟,而且該做些什麼且跟哪些人有關。這樣的能力在生活裡隨處可見,程式設計的原理也剛好不謀而合。

同樣的概念也發生在希望在程式裡達成一個目的時使用。想要做到的功能要去思考要由哪些動作來完成,那些動作各由什麼元件提供或是要另外做,能夠乾淨清楚地切出正確的動作並找到該負責的單位,是做所有事情所必須具有的第一種能力。

2007年11月8日 星期四

G05 做事的方法(9)──寫日記的方式

高二時曾寫過一本日記,那時的想法是忠實地記錄下每天生活的過程,也就是記流水帳。絕大部分對於寫日記的建議都說不要記成流水帳,要選擇特別的事情記下來,可是一直沒法理解為什麼要這樣。

開發與銀行相關的系統時,客戶很重視電子日誌的功能,這個功能可以記錄下所有使用者在系統上所執行過的任何功能與內容。由於銀行系統都跟錢有關係,所以需要這個機制在有狀況發生時可以追蹤到在什麼時間誰執行過什麼功能。這感覺上就像是在記系統的流水帳。

開發系統時,我們會記錄與系統有關的資訊與想法,因為這些東西在經過分析與規畫後,會使用想法更為融合與精簡,去蕪存菁後留下與系統開發有關的部份,藉此讓系統慢慢地成形並進而成功。我們並不會特別去記什麼文件在什麼時間點產出,因為內容會隨著時間再慢慢修訂,重要的是裡面所記下的想法。

可以發現前者只是一種記錄,便於在特殊要求時去找出相關的一系統事件;後者則是記下與成長有關的所有資訊,讓未來可以引證參考而能夠有更成熟的想法。兩種記錄的內容與方式恰巧對映在寫日記的類型。如果要的是在未來知道以前曾發生過的所有事情,適用第一種記錄法;如果要的是留下能打動心靈的瞬間,那就使用第二種記錄法,才更有機會反省並成長。

2007年11月7日 星期三

G04 驗收的文件(1)──需求階段相關文件

客戶對於想要做出來的系統,通常會有幾個大方向的資訊:

1、系統應用的範圍。提到的是系統的設計將會是應付什麼領域裡的功能所存在,這裡會提到很多使用者商業領域的相關知識。(Domain Knowledge)這裡的資料在設計時要產生系統詞彙表,並進而產生系統可以處理的Data Model。

2、系統處理的功能。提到的是系統將讓使用者可以做且要怎麼做哪些功能,每個功能的目的與進行的流程應被分析出來並明確記錄到需求規格書裡。所有需求都應被明確地定義出來並有清楚的流程後才開始設計。

3、對系統整體的要求與硬體配置。前者的清單會記錄著與功能的配合關係,並與硬體配置同時在作架構設計時視為最重要的參考資訊。有時客戶不是很明白這些資訊,在訪談時如有不清楚的地方要建議幾個方案給客戶選擇,客戶的決策就是系統確定要做的架構。

2007年11月6日 星期二

G03 文件是必要之惡?

開發系統的人幾乎都覺得寫文件是很痛苦的事,但是一些理論與公司規定卻又要求非寫出哪些文件不可,只好心不甘情不願的花時間敷衍了事。以前的我也抱著同樣的心態,但是在領悟應把心裡的想法留下記錄的道理後,就變得十分支持依系統開發的各個階段產出應有的文件。

設計人員通常會把瞭解需求之後的構思直接轉換為實作的程式碼,這對寫作的人來說是自然不過的事;系統的需求、需求如何轉實作、實作時的邏輯、物件的對應與使用等等很多的細節都是在他腦海裡的產物,當你拿到的只是開始的需求資料與結果的程式碼,要多少時間才能找出其間的演變關係?

順向依各個階段把心裡想法記錄下來是我現今堅持的理念,即使專案沒有足夠的時間,我也會依循文章裡提到的原則簡短地記錄。當文件成為想法一步步實現時的腳印後,就不需要做完系統才寫回憶錄而且寫了還完全沒用的痛苦,因為裡面寫的都是形成系統的重要概念與想法。

接下來就依系統各個階段的演進來看看應該會產生出什麼樣的文件與其代表的意義。

2007年11月5日 星期一

G02 建立系統標準安裝內容

程式開發完成並通過層層的測試後,那表示系統即將要可以驗收囉。但在驗收前最後的考驗,是把系統安裝到正式的環境裡作最後的線上測試;這也就是說,我們必須把所有開發出來的結晶作包裝的動作,以便客戶安裝到他們的電腦裡執行。

首先要知道的是每一部電腦對應的角色應該安裝哪些必須軟體,接著要知道各個電腦角色需要哪些建置好的程式檔案。另外,不管是系統的功能或是元件的使用,如果牽涉到其他公司的公用程式,除了在設計階段要註明使用的關聯之外,在準備佈署的時候必須參考使用關聯先行放置那些必須的檔案。

在基本佈署建立之後,再依層次向上決定每一個硬體所需的執行函式庫,還有系統執行檔,如此一來,每個硬體一層一層讓有哪些東西都可以決定。這樣的記錄將會延伸定義為執行硬體需求、軟體需求與安裝手冊,未來所有電腦的採購與安裝都需依照文件的內容進行。

2007年11月4日 星期日

G01 建立系統標準出版方法

針對系統開發的所有程式碼,在建立的同時應參考應用的場所與範圍來決定所屬的Package與Project,並依此來決定程式檔案的佈署配置。

Package通常會以功能的特性加以封裝,Class少的時候全部放置在同一層,多的時候再依用途再劃分Package放置,但嚴格來說會視作一個Component。把功能類似的Component放置到同樣的Project裡,並將Project的內容匯出成一個執行函式庫,同時依Component的使用關聯記錄Project的使用關係。

依據使用者需求設計的系統所寫的程式,同樣也依功能性分Package來存放,再將相同層次的程式依硬體配置擺放在不同的Project裡,每個Project再匯出系統程式檔。在不同的硬體上配置系統程式檔加上執行函式庫,就是使用者真正在使用的系統。

從原始程式建置系統檔案時,可以使用像ant之類的佈署工具,撰寫描述檔讓程式自動建立所有必須的程式檔案。

2007年11月3日 星期六

F26 系統應該被測試,想法應該被Review

系統應該被測試,然後除錯,以期望它能正常的運行
想法應該被review,然後修訂,以期望它能順利地實用

由於與同事討論程式設計的想法時,大多流落到局部面的思考,所以原本想藉這個Blog記錄對於開發系統時要有的全部想法,作為日後討論的依據。開始的時候試著用處理事情的思維加上軟體工程的角度寫短篇的文章,卻在不斷地思索之後慢慢發掘到更多要素的思維與影響。

雖然已儘量用主題表達方向,並使用簡短的文字帶出我的想法,不過我感覺只寫出心裡想法的四分之三左右;而更重要的是,雖然我覺得自己的想法說得通,但是不知實際上有沒有問題。於是幾天前在Java World @ TW論壇公開部落格的網址,讓自己的想法來接受檢驗並加以調整。不過一個沒考過SCJP認證又沒看過幾本書的人所說的話,理論上是不會有人進來多看的。

至今遇到過的人都還停留在“用程式做功能”的層面上,希望有那麼一天可以跟幾個理念接近的人共事,討論出實現軟體工廠的可行方式,並進而先“用程式做工具”讓很懂商業邏輯卻不大懂寫程式的人“用工具做功能”。等到那麼一天我們就可以有很強的競爭力了。

2007年11月2日 星期五

F25 客戶會在意系統開發的哪些方面?

在工作上一直都是廠商的角色,以公司的作法來滿足客戶的需求。用我現在的標準來衡量,如果我今天是需要採購一套電腦系統的客戶,我將會以下面幾項為出發點來審視:

首先是功能部分。系統最低限度是要滿足需求,除了由客戶提供功能清單之外,我將會檢視廠商如何記錄與控管所有的功能與流程的描述;尤其是需求規格書的內容。要是我可以決定測試標的內容,我一定會加上幾份重要功能的規格書審核。

接著是設計部分。我會檢查系統架構設計書上是否完整註明所有硬體與所用的技術?決策的過程是否有被記錄?當然設計規格書會是重頭戲,不過我著重的將會是Controller與Action的層次是否分明,另外看元件的層次是否整齊,系統的訊息是否獨立,功能上要求可以置換的地方是否採用夠彈性的設計。

測試將會是最看重的部分。測試的範圍必須與功能的設計相互呼應,藉此來保證所有功能都被完整測試;另外測試的時程與報告也是一定會看的重點。最後則是文件的內容是否切確地描述系統的安裝與如何使用所有的功能。

其實我覺得重點是在系統開始的時候,客戶就要用心投入系統的規劃,如此才能夠隨時隨地掌握住系統的狀況的內容。

2007年11月1日 星期四

F24 做事的方法(8)──做前三思,做後反省

生活裡總會遇到許許多多要作決策的事,之前提過做事要有目的與達成的步驟,但是在做之前還有個重要的決策:到底該不該做這件事?

在心裡快速地作沙盤推演可以是個有效的方法,把每個決定與作法都在心裡思考一下,整理出每個決策的優劣與影響並加以比較,如此將最有機會選擇到最好的決定。很快地作決定並不見得是好事,古人要我們三思而後行就是希望我們先確認再作最好的決策。

在學生時代寫考卷時,師長總會要求我們寫完要檢查;現在要問的是,要怎麼檢查才符合之前所提到的測試概念呢?每一個題目是需要寫答案的最小物件,所以在寫每一題的答案前應該先在心裡檢查一下對錯,這是Unit Test;每一個大題包含了該類型的所有題目,不過每一題間並沒有關係存在,這一層倒可以省略不用檢查;整張考卷會被批改並標註分數,於是把考卷視為系統再作一次檢查也是合理的要求。

做事前養成先想一下再做的習慣,一定會比先做下去再觀察反應的方式好上許多。這是在從事任何決定之前應該要有的習性。