现在的位置: 首页 > 综合 > 正文

結案之後

2013年09月07日 ⁄ 综合 ⁄ 共 22467字 ⁄ 字号 评论关闭

不久前,才把一個做了快要兩年的案子結束掉。有個年輕的同事就問我:
『奇怪,照理說結案應該令人覺得很興奮,可是為什麼我一點高興的感
覺都沒有?』

我們從小就聽了很多『從此以後,王子與公主就幸福快樂的生活在一起』
的故事。很多人可能就認為,專案應該像是做愛一樣,在末期努力衝刺
之後,就會達到最後的高潮,接著就在激情中,完成一個完美的句點。
所以到了那一刻,應該會讓大家心神俱醉,精神亢奮,快美難言。所以
常常都有人說,要召開盛大的party來慶祝專案的結案。

有這種期待的人,去看交響樂團演奏時,大概也會期待樂曲會遵照這樣
的模式吧。每首樂曲一定要在最後安排最大的高潮。在接近樂曲最後的
高潮時,整個節奏就會莫名其妙的加快,聲音會越來越大,跟男女交歡
差不多。等到樂曲尾聲時,所有樂器就會發出轟然一聲,然後就突然萬
籟俱寂,只剩下首席小提琴微弱地用他無力的手拉了幾個微弱的抖音,
整個演奏就此溘然而逝。還沒提他把琴弓抖一抖想甩去他的汗水的樣子,
與男性曳甲收兵時的景象有多神似哩。

我聽的古典樂曲很少,不知道有沒有這種奇怪的音樂,不過我做過的專
案中,還沒有一個是在激昂澎湃的音樂中結束的。有經驗的人告訴我們,
軟體專案的結案跟做愛不同,反倒是跟結婚蠻像的。結過婚的人都知道,
籌備結婚本身就是對兩人生活的第一個考驗。經過漫長的籌畫,把很多
瑣碎的事情都處理好,拍婚紗照,選禮服,訂場地,選菜單,選戒指首
飾,寄喜帖,送喜餅,遵照雙方家長認可的禮儀迎娶,行禮如儀,(都已
經什麼年代了,還要特地買把紙扇掉下來?)婚宴敬酒,等著被鬧洞房...
一直到把鬧場的人們從新房趕走以後,還得拖著疲憊的身軀,去面臨新婚
之夜與蜜月旅行。

很多小說都會描寫,主角在完婚之後,新人交杯對看,眼中深情無限,彼
此沉浸在綿綿密密,無邊的幸福中。或許你早就知道了,小說跟實際的生
活還是有段差距的。我只能說,如果你沒被灌醉的話,有不少人的標準感
覺是:『呼!終於結束了。好累啊!先好好睡一覺吧。啥?明天還要出團
去夏威夷蜜月?不會吧!』,接著倒頭呼呼大睡。半夜還被叫起來吵架,
因為今天你家的人還做錯什麼事情,引起枕邊人的不悅。專案結案時,感
受其實就很像是這樣。

當你辛苦了許久,經過了漫長的開發與驗收流程,終於讓系統上線了。你
認為任務已經了結了嗎?不,剛上線的系統可能會出的狀況最多。所以我
們需要繃緊神經,深呼吸,默默地解決所有沒有設想到的問題。該解的問
題也解完了,不該做的enhancement也做完了,跟客戶一直耗下去,終於
可以結案了。此時只會覺得如釋重負而已。把一個很重的東西從肩上放下
來,不會讓我們達到高潮,只會讓我們喘了一口大氣而已。

除了心理上的感覺以外,專案的結案,真的就代表了所有的工作都告一段
落了嗎?或許我們可以翻開軟體工程的書,看看有關於整個軟體開發經費
的統計圖表,如果你真的這樣做,你會發現Maintenance通常佔了整個軟體
開發經費最大的部分。

如果我們從經費這個層面看起來,結案之後,應該才是系統開發真正精采的
地方,要不怎麼我們會花這麼多錢呢?可是為什麼我們在學校裡面,好像很
少談到這一塊呢?

我記得小時候上有關軟體工程的課程時,在專案結案之後到底還要做什麼,
好像在書本裡面從來都沒有提到過。老師通常也是講完development process
,學期也就差不多該結束了。結案之後到底會發生什麼事情,god knows。難
怪很多初出茅廬,或是沒有結過案的人來說,內心總認為只要結案了,我們的
任務就已經了結了,感覺起來,好像只要系統上線了,從此大家就可以屁股拍
拍走人,每個人都可以就此過著幸福快樂的日子。

這可能也是因為有蠻多專案都來不及活到結案的時候吧。此外,就工程學上的
角度來說,這根本就不是討論的重點。他們重視的,是怎麼把東西給做出來,
或者說怎麼建立一套可大可久的系統,這看起來才有比較大的成就。蓋一間雄
偉的教堂,畫上金碧輝煌的壁畫,跟幫偉大的教堂修補柱子,重新替褪色的壁
畫上色,哪個有成就感,這當然不言可喻啦。

在這一章裡,我想討論一下關於結案之後的一些現象:

 ■很多案子驗收時,不管是schedule、scope或quality,都與原先規劃的相去甚遠
 ■上線之後,才是真正惡夢的開始
 ■scope/resource/schedule的弔詭
 ■文件通常沒有隨之更新。久而久之,只剩下考古的價值。
 ■系統做的越爛,越有保障。做系統的人吃定客戶找不到其他的人可以maintain。
 ■大多數做專案的公司,低估了保固期間的effort。取而代之的,是持續不斷的改版。

以下我想針對這幾種現象進行討論。

很多案子驗收時,不管是schedule、scope或quality,
都與原先規劃的相去甚遠
***********************************************

如果你找一個正在企業內部管理MIS系統的人,仔細觀察他的生活,你會發現他
的工作,有絕大多數,就是在於要想辦法讓現在正在運轉的系統可以持續運轉,
例如每天要幫新來的員工建email帳號,幫他們灌灌作業系統,教教怎麼使用公
司的系統,裝裝防毒軟體,印印報表,送修機器…除了這種看起來像是打雜的
事情以外,所謂的開發工作就是要不停地修修改改,以解決各式各樣營運上面的
需求。這邊多做一張不一樣的統計報表,那裡改改wording,修修程式的bug所造
成的data錯亂…。除了要參加無窮無盡的會議,來想辦法找廠商把舊系統換掉以
外,這幾乎是他工作生活的寫照。

很多從事MIS工作的熱血青年,如果他們在這個工作崗位上待到退休養老的觀念
還不是太重的話,只要有機會可以把手頭上的舊系統換掉,一開始一定手舞足蹈
,歡欣雀躍。認為只要辛苦一陣子,就可以萬事ok。可是通常等到歷盡千辛萬苦
,系統終於上線之後,常常會發現自己從一個火坑掉入另一個地獄。

我不知道你是否有過使用信用卡的循環信用或者是預借現金的經驗。很多人在刷
卡時,看到自己心愛的商品,一開始都會看到一個美麗的遠景。我只要付出小小
的代價,接著就可以解決我現在手頭上的燃眉之急。刷下去,就可以開始過我的
優質生活了。

通常等到東西買到手了,一直到回家以後才會赫然發現,怎麼這個東西也不過如
此而已?真是買貴了,還虧我還特地刷卡打算用循環信用哩。沒關係,廣告跟真
實中間總會有一段差距的。反正我急著用,有東西可以用比沒有好。接著等到開
始要付帳單時,這才發現:『糟糕,這個月又透支了,沒辦法了,只能動用循環
信用。我必須要維持良好的信用,不然就沒有信用卡跟循環信用可以用了。那就
繳個最低應繳金額吧。』接著內心就會開始暗自垂淚:『我到底還要付多久的錢
啊?』『下回再也不要這樣刷卡了。』

等到付款的時間過了,內心也懺悔的差不多了,接著就是要獎賞自己的時候到了。
嗯,應該可以再次計畫一個完美的刷卡購物之旅。

對於很多客戶來說,開發一個軟體專案,對他們而言,過程中的感受其實跟使用預
借現金或是循環信用差不多。一開始時,總會有一個蠻強烈的需求。覺得這個系統
一定要解決我們現在手上面臨所有的問題。通常要等到上線時,才會發現:『咦,
我們花了這麼多錢,怎麼就只有這些功能?我們還得要付出這麼多錢去做enhancement
喔?這簡直是一堆詐欺的騙子,在光天化日之下,明目張膽的搶劫。』只是這些搶錢
的人,不會拿著槍對你喊:『搶劫』。軟體公司最常做的是在他們的系統裡面埋下
一些炸彈,等到你走投無路的時候,再來獅子大開口。所以在開發的過程裡面,客
戶的內心,會不斷地在『有了這套系統,我們所有問題都會解決』的天堂與『我簡
直遇到一堆整天落後進度,追加預算的無賴』的地獄之間擺盪。

或許我們可以從一個假想的專案來體會這個情形。在某次客戶內部工作會議中,承
辦人正在向大頭進行報告,討論這個專案是否要進行:

業務承辦人凱莉:要達成總經理揭示今年的目標:『要用創新,效率,以及執行力
來重新改造我們的商業流程,讓我們可以更具有彈性,可以更迅速地提供給我們的
客戶成本更低,品質更高的產品。』(大企業教戰守則第一條,把大老闆的話拱出來
是不會有錯的。況且大老闆的話每次講的都是差不多的。)我們需要建置一套可以幫
助大家更有效率,更迅速做出決策的資訊系統。透過這套系統當作核心,可以幫我
們提供更完善的客戶服務。也就是說可以透過這套系統,達成高效率,高品質,低成
本的需求。當客戶滿意我們的產品,我們的營收與獲利都會獲得穩定的成長。公司賺
錢股票也就會上揚,才可以創造員工、股東、以及客戶的三贏。(反正我就是要做點
績效出來啦,要不年底發股票哪有份?)

大頭:你講的很抽象,依據你的評估,我們有沒有什麼具體的指標可以衡量這個專案
的成效?有沒有什麼KPI(Key Performance Indicator)可以參考?(官話打完了,講
點人話來聽聽。)

凱莉:喔,這在我的下一張投影片裡面會顯示出來,透過這套系統,可以把我們輸入
訂單的時間,從原來的30分鐘,大幅縮減到10分鐘。跨部門簽核的動作,可以透過單
一畫面迅速完成…(她滔滔不絕的講了很久,反正會有一堆編出來的好處。重點不在
於真正的好處有多少,重點在於你臨場時表現的有多鎮定,並且曼妙的身材,加上剪
裁合宜的衣服,成功吸引了多少色狼的目光。),根據估算,可以節省高階主管每人每
天30分鐘的作業時間。預計這種改變每年可以為公司節省七百萬以上的費用,還可以
讓我們回覆訂單的時間縮短百分之五十。

大頭:嗯,那預計花多少錢?多久開發出來?

凱莉:我們今年編列了五百萬的預算,打算在8個月內開發完成。

大頭:要這麼久?那個黛安,你們那個部門預計今年要做多少營業額?我記得我們上
次開會是決定你們要做20億,不是嗎?你對於這個schedule有什麼看法?

黛安:老闆,你記錯了,我們講好的明明是18億吧?

大頭(裝蒜中):哪有這種事?你們這群娘子軍這麼厲害,多做個兩億不算什麼吧。拿
出你們的gut來。

黛安(開會都已經講好了,哪有現在戴頂小高帽就要我多兩億,你當我神啊。每次都
這樣。):老闆,這個問題我們再另外開會討論吧。我們還是先回到這次開會的主題
吧。(不就是要我壓縮schedule嘛,這老狐狸。還要拱我出來做壞人。)業務部門的意
見是,如果要達成今年的營業目標,我想這套系統會是很重要的關鍵。業務部門是希
望可以在3個月內就可以看到成果。

凱莉(好個黛安,我上次開會前會時,都已經跟你說好,最少要半年了,現在來個3個
月):報告副總,我們已經評估過了,八個月已經沒有什麼buffer了。

大頭:我們也還是要照顧到業務部門的需求啦。這樣吧,我們先以半年內上線為目標,
剩下兩個月就當做是buffer。既然時間從八個月改成半年,我想應該花個三百多萬就夠
了吧?不要超過四百囉。黛安,那個營收的目標,我再找你討論。

凱莉想,Yeah!Bingo!Just make:報告副總,沒有問題。這個案子如果您核准了,我
們就可以開始進行後續的發包作業。

接著這個案子以385萬包出去。廠商一開始報了一年的工期,接著被凱莉要求要在3個月
內做完。最後成交的deal是在4個月內要可以上線。

布魯斯剛看到合約,吃了一驚:四個月?哪有可能?不是估了最少要一年的嗎?

吉娜:沒辦法,業務部門已經盡了最大的努力了。現在景氣不好,也沒辦法挑案子了。

四個月後,project當然delay了。凱莉好好地把布魯斯跟吉娜修理了一頓。不過內心暗
自慶幸:『還好我還有兩個月的buffer。』於是在status report中,還是報告:『目前
進度雖然落後,不過vendor已經努力趕工了,所以應該有機會在期限內完工。』

又過了兩個月。系統依然還沒有開發完成。才剛開始進入單元測試。

吉娜:布魯斯,penalty已經要開始了,你們現在到底狀況怎麼樣啊?

布魯斯:我們剛把程式寫完,要開始做unit testing啦。我每個禮拜status report都跟
你提過,這你也知道的啦。

吉娜想,真是個不懂得人話的呆瓜:我是說,因為我們有簽處罰條款,如果延遲驗收測試
的時間,是每天要罰錢的。你們現在到底有沒有東西可以給人家測啊?我們早一點進入UAT
嘛。反正只要開始進入UAT,就不會被罰錢了。反正只要系統會動,就可以給user測了嘛。
不管找出什麼bug,都是正常的嘛。反正UAT哪有可能沒bug。當初在簽合約的時候,我早就
預料到這一點了。

布魯斯想,又要這樣玩喔?這樣玩不是已經玩死很多次了嗎?怎麼永遠都學不會啊?:好啦
,如果你真的堅持,我安排下個禮拜開始就進入UAT。

吉娜:Good. Go ahead.

如果你沒有在出廠前,把unit test/ integration test…內部的alpha test做完,為了趕
進度就開始到客戶端進行驗收測試,提早進入UAT,對大多數人來說都是痛苦的折磨。進來
測試的user個個都發現這是個可怕的地獄。

咦,怎麼這個鍵不會動?咦,怎麼流程跑一半就走不下去了?咦,資料怎麼都是錯的?啊
,我這個月的事情做不完了,還要來測這個爛系統喔!

接著當然就會去review bug,依照大公司的習慣,咱們就來個defect review meeting吧。

在這次的defect review meeting上,布魯斯報告了defect的種類與數量,以及一些關於
defect的摘要資訊。

使用者代表辛西亞首先發難:我必須這樣子說,這根本就是在浪費我們的時間,我們要測
一個完整的scenario,根本就測不下去。我連最基本的輸入作業都走不完,這樣也要叫我
們測?

使用者代表蘇珊:對啊,這樣的品質怎麼有可能繼續測下去?凱莉,你說呢?我們浪費了
三天的時間也。三天也,沒有一個flow是可以走到完的。

凱莉:布魯斯,你們到底有沒有測過啊?你們這樣不行啦。自己都沒有測好,怎麼可以交
給我們測?

布魯斯想,我也知道會有這個問題啊,不過吉娜就要我進入UAT,我又不敢說不要:有啊
,我們內部的測試人員有進行測試啊。(是啦,有測啦,只是連單元測試都沒跑完。昧著
良心講話,這又不是第一次。)

凱莉:這差太多了吧。你摸著你的良心講,我們打開天窗說亮話,這樣真的有測過嗎?你
們還沒有ready,就不應該浪費我們的時間。

布魯斯做了不少辯解,不過後來的情況就是再多安排了幾次新的schedule,以及新的UAT。
與此同時,使用者越來越了解系統,對於系統也越來越沒有信心。接著就越來越覺得這個
系統跟他們要的不一樣。

很多change request,就這樣偷偷地溜了進來。因為schedule delay了,布魯斯對於
change request的抵擋能力也被剝奪了。吉娜答應了幾乎全部的enhancement。UAT從原來
的一個月,延長到超過了8個月,轉眼之間系統已經開發了一年四個月。凱莉也因此被大
頭們盯的滿頭包。

或許我們該看看凱莉這邊的故事。剛開始時。

大頭:凱莉啊,到底你們這個系統什麼時候會好啊?

凱莉:報告副總,我們現在遇到了一些問題,我想您也知道,系統開發總會有一些不可預
見的問題。現在廠商已經積極在處理了,我想這個月應該就可以有初步的成果。

大頭:要好好加油喔。這個系統很重要,我們業務部門已經跟我講過很多次了。希望它可
以早點上線。有什麼題需要幫忙的,盡量讓我知道。

就一開始來說,大家都沒有什麼deadline的壓力,所以氣氛一片祥和。接著是
project Delay了一個月。

大頭:凱莉啊,怎麼這個系統還有這麼多問題啊?現在狀況到底怎麼樣?

凱莉:報告副總,我們現在已經進行了一次UAT,user已經找到不少bug,廠商正在修,我想
我們修好了以後,可以在這個月再進行一次UAT,這次找到的問題應該就可以解決了。

大頭:push他們一下嘛。有必要找採購去跟他們sales談談。他們的主管是吉娜嗎?
我來給她撥個電話。

一開始delay的不算嚴重時,大多數的人都可以接受這種事實。因為每個人多少都為這件
事情抓了一個buffer。不過一旦超過了這個buffer,就會開始不悅了。我們可以看看
Delay了兩個月時的情形。

大頭:凱莉啊,你不是說這個月會再完成一次UAT嗎?現在狀況到底怎麼樣了?

凱莉:報告副總,我們現在已經再進行了一次UAT,不過這次還是沒有達到我們的標準。

大頭打斷:那你有什麼action plan?我們除了被動等他們修以外,還有什麼可以做的?
黛安已經跟我complain了很多次了。做事要有方法啊,我們怎麼可以被動的一直等他們修
?你要主動掌握他們的進度啊。好,從現在開始,你每個禮拜跟我報告進度。還有,黛
安跟我說,你們做的根本不是他們要的。

凱莉:報告副總,他們現在提出來很多東西,都是先前我們在規劃這個系統時,根本沒有
提到的。在需求訪談時也沒講啊。

大頭發脾氣了:真的嗎?不過因為這個案子的delay,已經造成他們作業上的困難,你還是
要請廠商解決啊。不然因為project delay造成的問題是要誰來解決?是你來解決嗎?難不
成是我?搞什麼飛機啊?公司找你們來,是要你做什麼的?

凱莉被凶了,不敢再多說什麼:我會盡力配合業務部門的需求。

通常,大頭們都會相信只要擠的夠大力,公牛都會被擠出牛奶來,如果這時你身陷在這個
專案中,最大的差別,就看你是那匹倒楣的公牛,還是無可奈何的擠奶工人。相信我,兩
個角色都不怎麼營養。

於是凱莉開始要求布魯斯每個禮拜交一份status report,以便讓她可以跟大頭報告進度。
同時她開始軟硬兼施地要求布魯斯要吸收change request。

又過了一個月。

大頭:再來看我們手上這個麻煩,凱莉,你說說看現在的進度是怎麼樣。

凱莉:業務部門提了總共有72個enhancement,廠商評估過了,這還要再三個月才做的完。

大頭發飆:三個月?那我今年的quota怎麼辦?你來揹?

凱莉默默無語。

大頭還在不爽:你們這些人做事就是不用腦袋,一點都不知道變通。你叫廠商想辦法先上一
個版本。你跟業務部門討論一下,先把主要的功能先上。剩下的我們慢慢再說。

凱莉:是。

一個phase的系統,變成了兩個phase,上第二個phase的時候,你就得要把現在的
production data,migrate到新的系統上。而兩套系統都需要測試,就會吃掉那已經很忙碌
的end user的時間。所以UAT的進度會落後的更多。很多出發點是想要讓系統變好的決定,
即使立意良善,也會因為沒有考慮到的邊際效應,造成了完全相反的結果。這種事情在開發
軟體系統時,屢見不鮮。

好吧,又過了很久很久,終於可以上線了。

大頭:凱莉,現在怎麼樣了?這個案子到底還要拖多久?

凱莉:業務部門的enhancement終於都做完了。而且我們UAT也過了,這一整個round都沒有
severity 3以上的defect了。只有10個severity 4的minor defect。

大頭:喔?這倒是一個好消息。這段時間你辛苦啦。等到上線以後可以規劃一下嘛,出國去
散散心啊。

凱莉:謝謝副總。我這幾天已經跟各部門討論上線的時間,包含人員訓練的時間,機器什麼
時候要shut down,migrate data…都已經在跟各個部門討論,等到有了共識以後,我會把
整個系統的roll out plan寄出來。

大頭:不要忘了還要寫一份contingency plan。比較major的task要做一份check list。等
到這個系統launch,你就可以好好休息一下。

系統終於上線了。剛上線的一個月,布魯斯的整個team,幾乎是日以繼夜地待在凱莉的公司裡
。終於,經過了兩個月,系統已經穩定下來了,這時候也開發了一年半了。

布魯斯:凱莉啊,我們配合了這麼久,你就不要再卡我的尾款了。

凱莉:可是我們還有25個minor bug還沒修也。況且上次你們程式錯亂,造成我們資料不正確的
資料你也還沒幫我們修啊。

布魯斯:你又不是不知道這裡有多少其實是enhancement,唉,反正我們都吸收那麼多了,不在
乎多個一兩個啦。你先把這個案子驗掉,讓我也做點業績。況且我們還有一年的保固期間。算幫
我一個忙。我們都已經一起co-work這麼久了,你就幫幫忙吧。

凱莉:好啦好啦,可是你不可以黃牛喔。那些亂掉的資料一定要幫我們改喔。還有這些bug,要幫
我們修掉。

布魯斯:沒問題。

經過布魯斯求爺爺告奶奶一個關節一個關節的打通,這個案子終於驗收了。這還算是有善終的。
我不只一次看到開發專案的客戶與專案團隊,在投入了大把的時間與精力以後,草草結束。除
了結果不如預期以外,所有投入的心血跟精力,幾乎也等於白費了。留下來的當然也是一堆難
解的爛攤子。如果想盡辦法讓它硬上了,也結案了,接著要面對的就是無窮無盡的bug以及
enhancement。

當你的scope,schedule,跟quality都與你原先規劃的差很多的時候,就等著再另外起一個
enhancement的案子吧。就是因為有很多案子都是醜醜的上線與驗收,這才讓maintenance會
變成一個無止盡的大黑洞。

上線之後,才是真正惡夢的開始
***********************************************
不管你做了多少測試,新系統上線,總會有你意料不到的驚喜。

有些時候,是因為你在測試時,並沒有辦法真實地模擬實際的狀況,例如一個網站,尖峰
時刻同時上線的人可能有一千人,可是你沒有足夠的資源,可以讓你模擬同時間有一千人
連上線的狀況。因此當實際上線之後,這一千個人加起來,可能就把你的系統給弄死了。

這讓我想到曾經在報紙上看到的新聞。大多數的男生都還蠻喜歡看A片,即使稱不上喜歡,
最少也不排斥。不過前一陣子新聞報導指出,警察查獲大規模的A片工廠,起出了數以萬計
的A片。因為辦案的需要,警方得要進行蒐證,也就是說每個人要日以繼夜地看完數以千計
的A片。他們得要整天盯著A片快轉,然後把會引起生理反應的精采片段,擷取下來,做為
呈堂證據。幾天下來,每個負責做這種事的警察,每個都性趣缺缺,人人都覺得是一種精
神上的折磨。

軟體系統也是一樣。有些人寫的系統,在使用人數不多時,看來一切正常,就跟正常男人
悠閒地在家裡面看A片一樣地輕而易舉,是一種令人愉悅的事情。可是當使用人數多到一
種數量時,這時就跟我們短時間內看了太多A片一樣,系統就會受不了,做出不太對勁的
反應。

熟悉測試理論的人都知道,這就是為什麼我們要做壓力測試的原因。對於壓力測試在做
什麼不太了解的讀者,我可以用這個例子來解釋,就是把一個男生的精子先榨乾,接著
開始放映一百部A片,要他盯著螢幕去看,而不會睡著。

在台灣,通常我們不會做壓力測試。即使做了,也大多都是做做樣子。因為我們大多認
為,我們的運氣不會那麼背。況且,對一個系統這麼殘忍,這是一件多麼不人道的事情
啊。不過實際上,你對系統仁慈,就是對自己殘忍。沒有好好測試系統的極限,等到上
線後再來收拾殘局,通常都是一件很辛苦的事情。

一般而言,即使我們要做壓力測試,我們也找不到那麼多的人來做真實的測試,所以大多
是靠軟體來模擬。然而透過軟體來模擬,畢竟還是跟真實的狀況有差距。再加上大多數的
系統都會有上線的壓力,所以稍微變通一下,總是可以想出一些辦法,做出可以接受的數
據,這種技術上的犯規,對大多數人來說,都是可以接受的結果。反正在大公司裡面進行
報告時,忙碌的大頭們多半就在看你最後的數據,誰會看你的假設?這就跟很多軟體在比
較效能時,每家都可以宣稱它在某方面贏過人家是相同的道理。基本上,沒有人說謊,只
是我們為了達成數據背後所做的努力,是你們沒有辦法想像的。

另一個問題也很類似,是資料的量的不同。我們通常為了測試時驗證資料方便,資料的筆
數會依照測試個案的數目來決定。真實的系統可能有上百萬筆資料,可是我們在測試時,
可能限於人力與時間,了不起就是有個近千筆資料。百萬筆資料跟數千筆資料有著非常大
的差距。因此,上線時遇到一些surprise,這也不是什麼了不得的事。可是真實上線時,
任何這種surprise,都會影響使用者的信心。

筆數太多所造成的最常見的問題,就是系統的performance不好,整個系統跟死掉差不多。
User沒有耐心以後,就想辦法把跑到一半的東西中斷掉,重新再來一次。跑到一半的東西
,再重來一次,這可能已經遠超過開發人員的想像了。會有什麼結果,通常誰也不知道。

例如有些人在資料庫的操作上下了max這類型的查詢,想找資料庫裡面的最大值。在筆數
少時,當然運作的輕鬆愉快啦,真的上線時,一旦遇上了,你就會聽到硬碟呻吟慘叫的聲
音。系統會賞你一個漏斗,搞不好數十分鐘過去了,還是一個漏斗。很多人一看到這種狀
況,直覺就覺得,這一定是系統有問題,系統當掉了。

根據我們從小使用電腦所累積的經驗,很多人還會伸出三根手指頭,卯起來把機器重開,
再試一次。弄個幾次以後,接著通常就會從三根手指頭,轉成開始罵三字經了,外國人可
能會把三根手指頭改成用一根中指來替代。有些時候,系統還真的有error message,例如
transaction time out那一類的。這時候當然就會上演三字經加長版。舉凡這種鳥事,通
常都在真的上線時才會遇到。

除此之外,使用者的操作方式,或是使用者所使用的電腦超出預期,也是上線時常見的
事情。

很多程式設計師的電腦,配備可能都不錯,特別是這年頭硬體越來越便宜,所以大家用
的電腦越來越好,幫自己的電腦升級,這是所有軟體開發人員最大的嗜好。如果不多插
一點RAM,實在是對不起這麼便宜的硬體。

可是在很多大公司裡,很多end user使用的,可能會是你無法想像的老舊配備。上面可
能是灌著一些幾乎已經快要絕跡的作業系統。遇到這種各式各樣的狀況,常常會有你無
法解釋的靈異現象會發生。例如可能這套系統有幾百個人在用,沒有其他人有問題,就
只有一個人的電腦,每次跑你所寫的程式就會當機。我們為了這種懶得解決的東西呢,
發明了一些術語,看起來比較有文化氣息一點,就會說這兩者『incompatible,就是不
相容啦』,沒那麼正式的說法是,這兩個東西『沖到』了。(作者註:有人說是叫相衝
啦,不知道是不是取互相衝突的含意。不過不管你怎麼寫,應該都解釋的通。)

我常常想『沖到』,這個名詞到底是從那兒來的。當我看到最近越來越多的命理節目之
後,才恍然大悟。所謂這套系統跟你的電腦上面所跑的應用程式沖到,指的就是你的八
字跟這套系統不合,就跟小孩子跟父母相沖,就會剋死家人一樣,是遵循著相同的理論
。所以如果你跟一套系統之間犯沖,每次只要是你要用,系統就會出問題;而別人要用
,就不會有問題。這表示你會遇到這個bug,最大的原因就是你的命不好,前世又沒有好
好修行,這輩子才會遭此劫難。準備好三牲酒品,應時水果,加上金銀財寶,再把電腦
扛去廟裡,請神明幫忙收收驚,再捐個一千塊點光明燈,應該就可以改善這個狀況了。
(註:我去翻了一下java週報,http://www.javatwo.net/javaweek/history/20030911.html
才看到洪志鵬先生也有類似的意見。果然是英雄所見略同。嗯,沒想到這麼容易就可以
自吹自擂地躋身英雄的行列。)

我遇過不少programmer,每次跟他們提到:『嘿,我在使用系統時,遇到一個問題。』
他們典型的反應通常是:『我的環境不會啊。』『在我的環境下一切正常啊。』『一
定是你操作有問題。』等到確定是因為環境造成的,他們通常的反應就是聳聳肩:『
早就跟你說,這又不是我的錯。這是因為環境不同造成的。』

大多數的人會視這種問題的存在為理所當然,所以也就沒有什麼預防跟改善之道,通常
就是遇到一個解一個。遇到不會解的,就可以宣稱,這是微軟的問題,你的windows需
要重灌…。我是不知道微軟揹了多少惡名,不過既然每個人的電腦裡頭,大多都用他家
的作業系統,暗示問題出在他家身上,應該是很管用的招數。

這年頭,每個人的電腦裡,到底存在多少奇怪的東西,實在是一個很難管理的難題。這
當然會使整個專案的不可預測性增加,不過話說回來,專案管理一直都還不是一門精確
的科學。『行到水窮處,坐看雲起時』一直是很多人的最高指導原則。反正就是且戰且
走嘛。

通常這種因為環境、操作順序的問題呢,它的嚴重程度(severity)呢,是依據發現者的
官位有多大來決定的。大頭們發現的,即使內容再無聊,都會被列為severity 1。反過
來說,如果你人微言輕,就會被放在defect queue的最後頭。

就是因為正式上線之後,所有意料之外的東西才會浮現,所以一個系統剛開始上線時,
通常就是惡夢的開始。當然,有很多方法可以降低正式上線時的風險。例如跟銀行有關
的系統,通常在測試以及系統上線的部分,會採取比較高的品質標準。不過對大多數其
他種類的商用系統來說,因為趕schedule已經成了家常便飯,所以通常不管你做了再多
的準備,多多少少總會有一些遺漏掉的部分,會在上線之後才跑出來。

這就跟新婚的夫婦,通常要到結婚後,才會發現枕邊人一些不為人知的小秘密一樣。有
些人為了避免這種婚後才開獎的surprise太多,會想要先來個同居。殊不知同居可以降
低surprise發生的機率,可是很難全然避免。同樣的道理,你可以進行很多次的pilot
run,可是正式上線時,還是多多少少會蹦出一些surprise。

<選美小姐機智問答>你跟同居很久的男人終於結婚了,等到要辦理婚姻登記時,才發現
一個天大的祕密,請問下列哪一種狀況最讓你吃驚?

 A.他還沒離婚

 B.他是個女的

 C.他不但是個女的,你一直以為他的肚子大不過就是個啤酒肚,其實肚子裡,還有個
  快要出世的小嬰兒

A這種答案,看起來就知道是來墊檔的。同居的人另外還有家庭,這根本太常見了。不足為
奇。B果然已經出乎意料之外了,不過C…這哪有可能?好吧,我選C。

根據宇宙小姐選美協會提供的參考答案是:『主持人,你一定在說笑吧,出來選美的人怎麼
可以跟人同居呢?這樣會被撤銷資格喔。像我這麼品行優良的人,頂多就是因為自幼家貧,
三餐不繼,只好在酒店裡面上班當會計而已。我要特別聲明,我可沒有坐檯喔。你看到週刊
記者所拍到的那一個削凱子的人啊,那是跟我長的很像的孿生妹妹啦。』

雖然花木蘭一直到退伍時,才被人發現她是個女的,這種事情簡直令人難以置信。不過現實
生活中,最大的surprise都是在開獎後才會湧現。很多人因為有了豐富的買彩券經驗,也就
都可以體會上線之後,才是惡夢真正的開始。

不過上線一陣子之後,惡夢應該也跟著結束了吧。很多人都是這樣想的。不過事情通常都不
是如此單純。這跟買房子付貸款差不多,房子不是付完自備款就了結了,真正的考驗,是後
面每期每期要繳的貸款。這就牽涉到下一個主題:『Scope/schedule/resource的弔詭』。

Scope/resource/schedule的弔詭
***********************************************
我們在開發一套系統時,會進行各式各樣的規劃。你會定義它的scope,決定要你會想想要花
多少resource,有什麼milestone要meet,每件事情,都會編造一個明確的schedule。可是對
於一個結案之後的系統,你會做些什麼樣的規劃呢?

通常,對於一套production system,大家會特別注意的plan,都是關於怎麼樣才能維持這套
系統的運轉。比較有規模的公司,會去規劃要怎麼做資料的備份,還原啦,system
administration時,應該遵詢什麼規則,遇到問題時,應該要怎麼反應,遇到緊急事件時,
要有緊急應變計劃(contingency plan)…

可是對於跟整個系統功能面有關的問題,除非有改版的計劃,否則我看到的通常就是:『
這套系統現在上線了,我們就找個專門的人來負責維護好了。』或是:『你就把這個問題當做
是一個bug,發到問題追蹤系統(bug tracking system)裡面,我們再來follow好了。』

因為我們通常都不會對一套已經結案,沒有任何明確改版計劃的系統進行什麼規劃,所以大
家對這方面通常都以等閒識之。『反正你就找個專人去負責。從今以後,他就負責這套系統,
任何時候,這套系統出了問題,你們找他就對了。』嗯,對主管來說,這真是piece of cake。
比較起來,怎麼開發一套系統,感覺起來才是一門學問,維護一套系統,感覺起來就比開發
系統容易多了,所以很多弔詭的現象,就會在這段期間不斷地湧現。

第一個問題也是最根本的問題:『scope的不明確。』

(續)

Scope的不明確
***********************************************
如果我們先把enhancement擺在一邊,那麼維護期間要處理的,就是把系統的bug給
解掉。對於一套已經在run的系統來說,到底會出什麼bug?這其實很難做估計。通
常我們能做的,頂多就是把bug按照嚴重程度(severity)來分級,再依據對於作業
面的影響,排定優先次序(priority)。

問題是,什麼時候會遇到severity 1的bug?除了老天爺以外,誰知道?

正因為這個問題的不可預測,所以我們都是遇到了問題解問題。

可是『遇到再說』…這算什麼planning?

有些人會期望可以從統計學上來看這個問題,不過一般而言,大多數人會把注意力
就直接放在改版上。既然不可預測,我們就發揮聰明才智,讓這套系統可以撐到改
版就好了。改版的scope,就把這段期間發現的bug一起包進來,再加上一些
enhancement,這樣就ok了。既然是改版,就會有一張新的合約,新的預算,也會
有新的project team,會為這個新的任務來進行規劃。既然有了新的project team
,就會重新就各個層面來思考這個系統現在跟未來會遇到的問題,大家也就不用傷
這個腦筋了。

對於還有足夠的resource來進行改版的系統來說,這未嘗也不是一個solution。不
過對於一套沒有改版計畫的系統來說,就只能賭運氣了。更何況,很多系統,都是
在有了enhancement的規劃之後,又浮現新的bug或是新的enhancement request。

凱莉:布魯斯,你們的這個系統怎麼這麼不穩啊?user又跟我report又有一個bug。

布魯斯看了一下,理直氣壯地說:等一下,這個明明就是個enhancement。

凱莉:這那是enhancement?

布魯斯:要不你拿出證據來,根據我們的分析文件,系統現在運作的很正常。完全
符合我們分析文件上的規劃。你們現在講的,根本就完全不一樣了。

凱莉:user跟我說那是你們的analysis document根本就不符合他們的requirement?
好啦好啦,這種東西我們已經吵了很久。反正我們現在已經針對這套系統起了一個
新的enhancement project,你就把它順便包進去吧。

布魯斯:這樣我要修改我們的報價。這個enhancement最少需要三個人月才有辦法
做完。

凱莉:啊你嘛幫幫忙,你們這麼強,這哪會需要三個人月?你不要忘了,你們的
enhancement才剛開始報價。我們可是還沒簽約啊。

布魯斯:要不你們enhancement可以找其他廠商來報價啊?(我就看你可以去找誰。
系統做的不好就是有這個好處啦。)

凱莉:哎呀,我們合作了這麼久,你就不要這樣子嘛。順便在enhancement project
裡面幫我們做掉嘛。我們今年真的是已經沒有足夠的預算來做這個案子了,連
enhancement都是我們處長到處張羅來的。況且,如果你要再改報價,那合約大概就
要再重跑一次流程,你們最快也要再一個多月才會拿到頭款。幫個忙啦,現在有人
手就先做掉啦。

布魯斯被打到罩門,吉娜才剛剛跟他說,公司最近現金有點緊,希望可以跟客戶拿
一點現金來幫助資金調度:我跟development team研究看看。

對於一套已經在running的系統來說,維護的人到底要做些什麼其實很不明確。而最
討厭的,是政治力的干擾會特別嚴重。一個做好的系統,就像是個練功的靶子一樣
,任何一個高階主管,只要想證明他的政治影響力,或者只是單純的無聊,都可以
發表他的高瞻遠囑一下,而這些東西,通常會被當做priority 1的issue來處理。

例如:

處長請他的秘書寫了一封email過來給凱莉的老闆:『你們的這套系統是比舊系統好
用啦,不過在主管簽核後,不要每張單據都發一張notice出來嘛。這樣我的email都
快被你們這些垃圾信擠爆了。』

凱莉的老闆收到信後,馬上召開了一個緊急會議。會中決定,這是top priority issue
,因為『處長講話了。而他唯一的comment,是這個關於email的小問題。我們當然要
盡力而且盡最快的速度,達成user的需求。』於是布魯斯,用最快的速度,把人抽出
來解決這個小問題。這個簡單,反正就是把信都檔掉就好了。

新功能上線沒多久,稽核室寫了封email來:『這樣不符合我們內部控制的原則喔。』
請示過處長後,處長說:『你們這些笨蛋,我只是叫你們把多封email合併成一封,
誰叫你們把email notice停掉?』

這件事當然被當作top priority處理。新功能上線頭一天,總經理的秘書轉寄了一封
信給處長,處長打開一看,裡面只有一個問號。下面則是幾位副總經理的假單。當下
立刻大吃一驚。原來布魯斯他們在趕工時,沒有把總經理的email排除在外,想想看
,總經理是日理萬機的人,哪會需要看這種東西?好死不死,今天他心情好,除了秘
書以外,他自己還在看看他的email信箱有些什麼信。就被他發現這個bug啦。整個
project team因此被罵到臭頭,這也不是什麼意外的事了。

就是因為你要做的東西大多是一個一個很瑣碎的需求,所以雜事特別多。做這種雜事
,是非常沒有成就感的。這也就引出下一個問題:『大多數開發系統的人,都不想
maintain別人的系統。所以我們通常都派最資淺的員工去maintain一套系統。』

大多數開發系統的人,都不想maintain別人的系統。所以我們通常都派最資淺的員工
去maintain一套系統。
***********************************************
古人練劍時,練到極致時,常有所謂劍在人在,劍亡人亡。不過根據我的觀察,這種
東西在資訊業界並不存在。取而代之的是:『系統在,人絕對不在。任何一個了解一
套系統的人,都會因為某種原因離開這套系統。接著,系統就會隨著時間的推移,移
交到一個超級不適任的人手上。』(作者註:在物理學上,這好像叫做熱力學第二定
律。)

一個人可能會因為一套系統開發的很好,所以高昇去做小主管了;也有可能是因為他
的薪水,隨著年資的增長而成長,所以他被調整到需要揹負更重大的責任;也有可能
是因為他自己想要多摸一點其他的東西;或者是他受不了這麼無聊的工作,就屁股拍
拍走人了。可能的原因很多,不過每個人都會因為各式各樣的原因而離開他所熟識的
系統,換個菜鳥進來。

如果菜鳥接的不錯,沒多久,就會因為類似的原因被調走,再換一個菜鳥進來。反正
每個系統早晚都會遇到一個終結者,會讓這套系統在他手下開始沉淪,接下來的連鎖
反應,則是會讓這套系統走向萬劫不復的境界。

通常的模式是這樣子的狀況:

1.頭痛醫頭,腳痛醫腳。因為不熟,所以改出一堆問題。
2.改出的問題,越來越多,菜鳥沒有能力解決。
3.開始沒有力氣去更新文件
4.開始嚴重落後進度。主管被罵了,所以會找個熟手來幫忙。
5.熟手解決了一部份的問題,可是因為他不了解最新的狀況,所以埋下一些他自己也沒
意識到的炸彈。接著系統看起來迴光反照了一下,重新展現出生命的活力。接著熟手
就因為階段性任務結束,就回到原來的工作崗位。
6.炸彈爆了,菜鳥繼續去解。
7.菜鳥因為一直解不掉,又被人K到受不了,遞辭呈了。
8.沒有人知道菜鳥到底對系統做了些什麼。
9.熟手硬著頭皮去亂改。拖過一陣子後,趕快找機會開溜。主管找不到願意接手的人,
找個更菜的菜鳥來接手。
10.回到2。一直到這個系統被時間淘汰。重新做的人,通常跟原始的team已經沒有淵源
了,所以犯過的錯誤,吃過的苦頭,會不斷地重複出現。

所以就resource來講,最適合的人通常都待不久,不適任的人,則是會一直濫竽充數下
去。這也讓maintenance變成一個越來越難解的難題。基本上這會是個惡性循環,不過
要打破這種惡性循環,要改變的觀念實在是蠻多的。組織要透過學習來導正這種觀念,
其實是一件很困難的事情。更何況很多人根本沒有意識到這件事情的重要性。

除了人的素質以外,另外一個很有趣的問題在於人的數量。一套系統,可能開發時總共
有十個人在開發,每個人寫了個三萬行程式,所以總共有三十萬行程式要維護,可是到
了維護階段,我們常常是只剩下小貓兩三隻在接手。一套系統只有一個人維護的狀況屢
見不鮮。

在開發階段,每個人只要負責三萬行,可是到了維護階段,一個人要接手三十萬行的東
西。就比例上來說,實在是很不相配。

你可能會說,接手的人,並不是在創造新的東西,只是需要拾人牙慧就可以了。這相對
來說比較簡單。問題是,當系統出問題時,你搞不好就是要把別人花了許久的心血給鑽
研透徹了,才有辦法找出問題,並且解決問題。三萬行跟三十萬行,這中間的難度差異
,相去不可以道里計。

你要改別人的系統,照理說你得把別人的東西都讀通了,才有辦法開始修改。不過系統
出毛病時,通常你的各級主管們,根本就等不及你對系統有任何概念,就會要求你開始
解決問題。然後站在你的後頭,盯著你的螢幕發呆。很多人在趕鴨子上架,不知道從何
下手時,就會選擇比較安全的做法,也就是站在古人的基礎上繼續下去。所謂的疊床架
屋,就是這麼回事。

或許你不清楚什麼是疊床架屋,我在此做個小小的說明。

系統的程式不曉得哪裡出錯了,原先不應該寄給總經理任何信件,現在卻會把副總經理
的假單寄給總經理,要求他來核准。這時候最簡單又最快的做法是什麼?找遍所有的
source code去看bug在哪裡嗎?Oh, my god.當然不是。答案是在要寄信之前,凡是遇
到要寄給總經理的狀況,就把這段程式給跳掉。先看是不是總經理,如果是的話,套一
句韋小寶的名言:『老子不幹了』。不寄給你總成了吧?我們不過多設一個參數,叫做
『總經理的email』,接著再多一個if then else的判斷而已。Piece of cake,no big deal。

//start for defect 198

if document.email =總經理的email then

system.out.println(‘這是大頭目啦,老子不寄了’) //不要寄信給大頭目啦

else

document.sendmail()

end if

//end for defect 198

很多人就這樣卯起來改bug,把原有的結果丟到資料庫,還是丟到檔案裡面,接著寫
另外一支程式,去把原有的結果讀出來,加上我們要的新邏輯,再丟到一個新的結果
檔裡面。或者是直接拿新的結果把舊的結果給覆蓋掉。問題的根源呢?可能誰也沒力
氣去改了,那就這樣吧。反正問題已經獲得了解決。

多幾個人這樣搞下去,整個程式的架構就變成一團混亂,誰也搞不清楚,原來寫的人
,到底想幹什麼,後來改的人,又是為了什麼狗皮倒灶的原因,又寫了一堆有的沒的
周邊程式。今天把總經理的email跳掉;明天又因為某個部門在抱怨,所以遇到這個
部門的主管時,要cc給這個部門其他的主管;後天又要把mail密件附送給部門的秘書
…這樣一路下去,系統就這樣越長越胖,越來越慢,變成一支可怕的巨獸。

所以對於維護一套系統來說,Scope難以界定,resource良莠不齊而且人力不足,接
下來受傷的當然就是schedule。偏偏schedule又都很短。這就帶出另一個弔詭:
『問題越來越困難,可以用來解問題的時間,卻越來越短。』

問題越來越困難,可以用來解問題的時間,卻越來越短。

使用系統跟使用循環信用差不多,你用的越多,你對它的依賴程度就越大。可是你的
胃口,卻會被循環信用慢慢撐大。直到你無法解決。

在某家不大的公司裡,現在是某個月的1號,使用者瑪莉使用她的系統來產生月報表。
就在這時,她發現系統有個bug,該顯示的資料沒有全部抓出來。她馬上打電話給公
司裡面負責維護系統的MIS工程師艾力克。並且解釋了她所看到的狀況。

瑪莉:你們這個bug要修多久?

艾力克:關於這個問題,如果真的要我講一個期限的話,我想……會是一萬年。

瑪莉:該死,不要開玩笑啦。我這個月5號要交報表。而現在筆數根本就不對。

艾力克:我看了一下資料,這些資料都還在,應該問題不大。我明天趕給你看看。

瑪莉想,嗯,明天就有了,這樣很好啊:ok。

過了兩天,瑪莉拿到她要的報表。雖然晚了一天,不過這個月順利過去了。又過了幾
個月。瑪莉發現這張報表的數字不合。簡單的?就是明細加起來的數字,跟總計不對
。而她因為報表已經順利印出來了,就沒去管它,先去忙別的事情。一直到三號才有
空去對報表的數字。這才發現事情不好了。連忙打電話給艾力克。

瑪莉:要死了,要死了,這張報表的數字不合啦。

艾力克:莫驚莫慌莫害怕,施主切勿心急,待貧僧仔細觀來。

瑪莉:哎呀,我後天就要交報表了啦。完了完了,趕快趕快啦。

艾力克:關於這個問題嘛,讓我仔細思考看看…

瑪莉:啊你嘛幫幫忙,不管啦,你今天一定要修好啦。我陪你加班。

艾力克:好啦好啦。我今天趕給你。

艾力克連續抓了兩天的bug,每天只睡兩三個小時,終於讓他抓到問題的所在。這次運
氣不錯,讓瑪莉順利在五號交出報表。到了年底,系統出了其他的問題。而這一次,
很大條。

瑪莉:艾兄,大艾先生,幫忙喔,救人喔。我的系統當掉了啦。我執行年度作業以後,
整個系統當掉了啦。

艾力克:你跟我講一下操作順序。

瑪莉:我就年度作業給它run下去,系統就跳出藍色螢幕,要我通知系統管理員,接著
就自己重新開機啊。我現在開機以後,連動都不敢動它。就趕快打電話給你啊。

艾力克:這麼嚴重啊,你不要吵我,我過去妳那裡。

艾力克到了瑪莉的電腦旁,開始認真的研究,接著在旁邊把他自己的notebook連上網路
,看系統的log。他看了將近一個小時,臉色凝重,平時的嘻皮笑臉已然不見。瑪莉在
一旁,不知說什麼才好。終於…她忍不住了。

瑪莉:這個問題很嚴重嗎?

艾力克:嗯。

瑪莉:什麼時候才會好?年底到了,我要報資料給財務部說。

艾力克:不要吵啦。你剛剛run的東西,剛好是在執行server上一堆stored procedure。
這支跑到一半當掉,我還在看log,看看到底跑到那裡,要怎麼recover。

瑪莉聽不懂:喔。那你要幫幫忙,快一點喔。加油!加油!加油!我去買杯飲料給你喝。

這次的問題比以前都嚴重多了。系統執行的程式,把瑪莉電腦裡的記憶體吃光了,接著開
始使用硬碟來存取資料。而瑪莉的硬碟在慘叫很久之後,產生了壞軌。所以系統送她一個
藍色螢幕當紀念品。很自然地,這次的問題,花了快兩個禮拜才恢復正常。

一套系統run久了以後,每個人都會把它會正常運作視為理所當然。即使是bug很多的系統,
run久了,每個人對於會遇到什麼樣的bug,大概心裡多少都會有個底。所以系統執行到半天
,它就會當。沒關係,重新開機後再重來一次就會好了。這個功能系統會做出一些錯的資料
,沒關係,反正一個月就是個幾十筆,我們人工改改就好了。Life will find a way.
So is the system.我們總會找到一些方法讓系統可以跑下去。

不過用久了,系統常常就會在你意想不到的時候,跳出幾個罕見的大問題。因為我們已經
習慣了有個可以預測的系統了,這時如果出乎你意料之外,通常可以反應的時間就會很短
,可是要解決的問題,因為前所未見,所以可能不是那麼簡單。時間通常只夠找出最快的
turn around solution。讓系統可以活下去,繼續用。

做出turn around solution後,我們通常不會有時間做很正式而完整的測試。然後就把這
個patch上到系統上去。很有可能就在這個時候,會引進了新的問題。所以我們就會急急
忙忙地花大多數的時間,嘗試著去修正錯誤,與此同時,製造出更多的錯誤。

所以對於一個正在運轉的系統來說,stability才是最重要的。要是它沒壞,幹嘛修呢?
多一事不如少一事,少一事不如根本就沒事做,沒事做的話,還可以利用上班時間,上
網看沒穿衣服的美少女。這是MIS人員特有的福利。於是乎,你根本就只是應景的提出一
些改版計畫,或是一些無關痛癢的小幅更動,最好不要替自己找麻煩。養老的心態越強,
就越不會對於維護系統做什麼長遠的規劃。

Scope/resource/schedule之間的互動,就是專案管理最重要的幾個關鍵。可是對於一套
進入Maintenance mode的系統來說,我們其實在這個地方思考的並不多。那也就是為什
麼,一套系統的maintenance cost會是整個life cycle裡面最高的。不過要克服我們這
一節裡面所遇到的弔詭,並不是那麼容易的事情。因為它牽涉到的,主要是管理者的既
有觀念。而觀念的改變其實是相當困難的一件事。

有很多外行的主管,壓根兒就不知道民間疾苦,跟貧戶之子一朝飛上枝頭做鳳凰之後,
就忘了有個公平的聯考以及人人有能力上大學,是多麼好的一件事一樣。這樣說起來,
從基層做起的主管,應該就會表現的比較好。

這也不然。從基層做起的主管,在思考維護系統的問題時,常常會拿他自己對於系統的
認知,來進行估計與指引。這時候錯誤的認知,其實會影響他做出正確的判斷。

布魯斯:這個問題,只要把這兩個table的東西join起來,另外create一個table,再把
結果insert進去,接著,再寫程式去把這個table的東西讀出來,再做點加工就好了…嗯
,我看應該一天就可以寫完了。這樣吧,我想我們就訂兩天寫完好了。

丹尼爾心想,那有可能?:……

布魯斯:有困難喔,那不然就是三天吧…

過了一個禮拜,東西才寫出來。

布魯斯:奇怪喔,這個問題,怎麼會要做這麼久?我記得以前這個問題,我們大概都是
一天就搞定了。

丹尼爾心想,是喔,是幾百年以前啊?:系統變得比以前複雜很多啦。

對於系統有概念的主管,常常會忽略掉每個人的學習曲線應該會有所不同,也很容易就會
忽略掉系統的演進,會帶來複雜度的增加。更重要的是,因為他沒有掌握系統所有演化的
細節,當他在發號施令時,常常就會給一些不是那麼正確的指示。而且還要求程式設計師
要完全遵照他的指示去做。如果他不幸言中,還會跟你嘮叨一些『我早就跟你講過了。』
『不聽老人言,吃虧在眼前。』

過猶不及都不是好事。就因為每個人都會受到他的認知的影響,所以要不就是沒有規劃,
要不就是規劃的不符合實際需要。所以我們在維護系統時,考的都是臨場的反應。反應的
時間很短,自然造成邊際效應的機率也會增高。邊際效應一旦產生,你就會陷入解bug、
沒時間測試、趕快上新code、製造了新的bug…的循環。

當你落入這樣的循環,這時文件的更新常常就是變成一件有空再做的工作。累積久了就會
什麼都沒做到。這就會引出下一節的主題:『文件通常沒有隨之更新。久而久之,只剩下
考古的價值。』

文件通常沒有隨之更新。久而久之,只剩下考古的價值。

關於在軟體開發的過程裡,到底要寫什麼樣的文件,才是足夠的,一直沒有一個很好的
標準答案。某種原因來說,也是因為每個人要做的系統不同,觀點不同,也就一直有著
不同的理論。

我曾經寫過一篇文章,表達我個人對於Use Case driven的OOAD開發方式的看法。或許是
因為沒有特別強調,所以很多人認為我是堅決反對採用這種方式開發的人。

如果真的造成這樣的誤解,這真是冤枉大了。我怎麼可能會放過這種向大師與流行趨勢靠
攏的大好機會呢?或許是因為我沒有表達的很清楚,才會造成這樣的誤解。

我原本想表達的含意是如果使用Use Case driven的OOAD方式來開發跟資料庫應用相關的
程式的話,那麼採用這種方法,我個人覺得並不像採用傳統的結構化系統分析來得適合。

事實上如果你需要描述actor跟系統之間非常複雜而頻繁的互動關係的話,採用
Use Case driven OOAD,其實是很適合的。這世上還有很多系統,是跟資料庫無關的,像
是文書編輯軟體,繪圖軟體,影像處理軟體,網路通訊軟體…,這些東西哪有什麼
data flow diagram?你不用use case來描述,我還真的會覺得你要不要去看一下醫生哩。

主要是因為每個人做的系統特性不一樣,就應該採用不同的方法來進行開發。我以為這就
跟為什麼男生的內褲應該開個洞,女生的內褲就不用這麼麻煩一樣,是相當淺顯易懂的普
通常識,不需要特別強調。

不過後來才發現,對於大多數人來說,這種推論並不是那麼直覺。很多人做系統時,並沒
有那麼多的開發經驗。所以都是聽公司裡面的超人說說,就決定要遵循某一套開發流程,
撰寫某一種特定的文件。

接著採用一種方法,做過幾個案子之後,就會有一定的看法。接著,常常就因為公司的長
大或是自己的職位也往上爬了,就要開始參與『制訂公司標準程序』的討論。

對於很多主管來說,應該要建立一套可大可久的制度,並且要訂定標準的作業程序,這樣
開發出來的軟體,才會符合一種持續改善的水準。這聽起來多麼地言之成理啊。所以制訂
公司標準程序,就變成了公司裡面的老手大拜拜。沒有多久,就會被拱出來談一次。

正因為通常參與討論的人,都有不同的經驗與背景,所以在蠻多公司都會有方法論的戰爭
。簡單的講就是要寫什麼文件,要畫什麼圖,只有我講的才是對的,你們根本就太過天真
,沒做過真正的案子。訂定標準是需要開戰的。每個工程師對於要寫什麼文件,通常會有
很枯燥乏味的辯論。越強調民主的公司,這種辯論就越冗長。

到最後,常常政治角力的結果,就是什麼死人文件都寫。有些公司還會定義出很多標準,
所以到最後,就會變成是為了寫文件而寫文件,為了符合文件的標準,而寫文件。對於大
多數剛出社會,就踏入軟體開發業的年輕朋友來說,其實他們剛開始工作時,都會想要照
著規矩跟process,好好地寫文件。如果這時後又接收到莫名其妙的指示,菜鳥們因為對
於系統開發也不熟,就會一方面會寫出奧妙難測,不知所云的東西,另一方面還認為遵循
系統開發標準流程很重要。

對很多人來說,他們並不知道為什麼要寫這份文件,也不知道寫了它應該要發生什麼功用
,只知道,這就是標準,這就是大師的金玉良言,這就是宇宙運轉的定律。跟地球會繞著
太陽轉一樣,是無庸置疑的。可是正因為他們不了解為什麼要寫這些文件,以及文件與文
件之間應該有什麼因果關聯,所以就是虛應故事,為了寫文件而寫文件。這世上比這還無
聊的事情應該也不多啦。

所以常常到後來,文件便不是開發軟體時,輔助思考的產物,而是像小學生要學寫字一樣
,得要照著筆劃抄寫的作業本。人菜的時候都比較好騙一點,所以菜鳥們通常都會寫的很
高興。可是日子久了,就會發現,為寫文件而寫文件,其實是很浪費生命的一件事。

當他不了解一份文件到底是為何要寫時,如果遇上一個很緊急的bug,第一件事當然是趕
快把錯掉的程式改到對。或是找出一個可以解決的臨時方案。然而對於一套系統來說,問
題其實常常是層出不窮的。每天在救火,久了之後,通常就沒有力氣去更新文件。

對很多程式設計師來說,維護系統時,該過著什麼樣的生活,選擇只有兩個。

A.趕快把bug解一解,接著就可以準時下班,陪女友聊天看電影,到山上海邊看星星
月亮與日出。文件管他去死。

B.乖乖寫好文件後,再去解bug,因為加班到深夜,結果半夜回家時,還被喝醉酒的
汽車撞到,在救護車上,女友還打電話來說你都冷落她要求分手。

想要活得幸福的人,通常都會選擇正確答案,也就是A。如果因為沒有follow標準流
程,良心會有些許的不安的話,就會記得在拜拜時,多添點香油錢。

只要在維護系統的過程中,有一個人沒有更新文件,接下去每個接手的人就會越來越
沒有辦法來更新這些莫名其妙的文件。因為東西只會越來越亂。久而久之,文件就會
變成只有專案考古學上的價值。所有的真理,就只會躺在程式設計師所寫的原始碼中
。而原本有用的文件,就會因為年久失修,變成徒具參考價

抱歉!评论已关闭.