發表文章

課程改進

今年在輔大招開的TSCE11,其中在Panel Discusion中(主題:軟體核心能力),我提議軟工教育訓練由OO modeling概念開始,而程式則依據models來撰寫,這種提議可能須修改教學程序,不過我認為,「軟體核心能力」的目的乃是要建立優良的軟體系統,而models比複雜的程式容易描述系統,也比較容易保養系統,因為其抽象層次較高,也符合程式語言以及軟體發展方法的演變之故。我提出這種意見,希望對軟體工程教育有興趣的人士能夠討論,提供意見。

蓋房子和寫軟體

往花蓮的自強號上,旁邊坐著一位五十幾歲的長者,一直反覆的看著一本旅遊書籍,看起來是歐洲旅遊的書。我好奇便問他:『剛從歐洲旅遊回來嗎?』,他嚇了一跳,我連忙向他道歉,他親切說;『沒關係』,接著很興奮的告訴我他的攝影心得,就這麼聊了起來。 他一邊翻閱書上的照片,許多的地方他都去過,他說他喜歡研究別人取景的角度為何和他不同,借此學習更好的攝影技巧。看得出他對生命充滿熱情,喜歡思考、創作與分享。聊著聊著才知道他原來是台中知名建商的董事長。 除了生活上的樂趣外,他也跟我分享他的經營理念。他對員工的要求是 『不能凡事都照著規格書、設計圖走,那是官僚』 。為什麼?他們的員工每天都在接觸房子的買賣,久了就麻痺了,以為房子的買賣很輕鬆,但是對許多買房子的人可能是畢生的積蓄,一生可能只買一次房子。 他說他接觸過很多醫生、教授或高科技產業的客戶, 他們在自己的領域上十分的專業,"但對房子的事情真的就是不懂" ,所以不能拿規格書來壓他們,應該是要幫助他們。 姑且不論這位董事長是否真的做到這樣的原則(畢竟我跟他不熟),這些道理在軟體工程產業上也是相通的。寫軟體的如果在客戶搞不清楚規格的情況下一直以規格來壓客戶,那就是以專業的傲慢來欺騙客戶的無知。 當然,蓋房子跟寫軟體畢竟不同,各位覺的呢?

有理說不清

軟體系統常常背上許多莫需有罪名,有時候是需求的提供者沒把需求說清楚(或根本說了錯誤的需求),有時候是使用者不會用 (沒參與教育訓練或沒看說明書)造成操作不當。當後者的情況發生時,使用者通常會怪罪『介面設計不好』。 的確多數的軟體工程師對於介面的設計不重視也不在行,但有時候使用者也太無理取鬧,把所有的錯誤都賴在介面設計上。 張大叔最近開始使用線上照片沖洗的功能,但照片卻遲遲沒有寄到,他上網查了一下,發現住址寫錯了。他打電話到客服中心發飆。 『你們的系統有問題不穩定,把我家的地址記錯了。明明是100號,怎麼會記成200號?』 客服查了一下,回應說: 『張先生,有可能是您打錯了,系統記錄的的確是200號』 『怎麼可能?我打過無數次了,怎麼可能會把自己的住址打錯?』 客服有耐心的說: 『有可能1和2相鄰,您打的時候打太快了,所以不小心打錯了』 『那你們系統要做檢查嘛,哪有那們笨的系統?要做防呆嘛』 客服楞了一下,還好他邏輯還清楚: 『張先生,我們系統不知道你住100號,怎麼知道您打錯了?沒有辦法喔...』 這下換張大叔楞了一下,但他還是很生氣。 『這照片是我送給老婆的生日禮物,照片我選了好久,沒有按時寄過來這個禮物就沒有意義了』 ,頓了一下又說: 『你們要怎麼賠償我的損失?』 『先生,這是您打字錯誤所造成的,我們沒有辦法賠償。我們會通知郵局將包裹重寄,但您要再負擔一次運輸費用』 客服說。 張大叔一聽還要多負擔就生氣: 『都是你們系統的問題為什麼要我負擔?你們介面設計的太糟,介面要儘量防呆嘛... 比如說不要讓我們用打的,讓我們用選的...』 客服有點聽不下去了: 『先生,忠孝東路門排很多,我們不可能把所有門排都列出來讓你選』 『怎麼不可以,你可以每一個位數都用一個下拉式選單,三個位數只需要三個下拉式選單,你們設計要用點腦筋嘛』 ...

問題解決

古時候,中國有一則寓言是說:有四個人走到一面高牆前面,高牆的通門用鐵鍊與鎖鎖住,其中三人試圖用盡各種方法要打開門鎖,用石頭打、火燒、以及用木棒挖鎖等方法,但最後仍然無功,這時候,忽然看到那第四人從森林走出,手握一把長竹竿,走到牆面前以撐竿跳的方式跳過那一面牆。 第四人並沒解決門鎖的問題,而是避開重新定義問題,創造新的而可解決的問題 ,因此基本上問題不在門鎖,而目的是人要到達牆的另一面。 這則故事顯示,"what"與"how"的問題,前面三個人只想『我如何打開那道門』(how),至於另外一個人則避開那三個人的困境,只是想『我要做甚麼』(what),答案是『我要過那面牆』,一旦他將問題放在"what"上面,他就可以設計如何執行而獲得成功,他解決問題不只是解決,而是問題要合理解決。 發展軟體就應如這則寓言中第四人的作法,要如何達到有許多方法,其中CRC cards (Class-Responsibility-Collaborator cards)技術,可能是最佳方法之一,但似乎未在國內引起廣泛注意,我們另文討論。

從種樹小故事看流程改善

今天上課前突然想到一個故事,稍作改變後用來跟學生講解流程改善。 某公司聘用一個員工上種樹,他需要鋤頭挖洞,將樹植下,最後再用鏟子把地鏟平。以他的速度一天只能種十顆樹,比老闆預期的進度差太多,於是老闆又聘了兩個人來幫忙,速度提昇了兩倍。 [from work harder to work smarter] 但是這樣的速度還是不夠快,而成本又太高已經沒有經費在聘用員工,只好想辦法進行流程改善。他仔細觀察三個員工的工作方式,發現花在工具的抽換花了太多的時間。於是他重新更換了三個人的工作:A 只做挖洞的動作,B 隨後將樹植下, C 隨後在將地鏟平。這樣的工作模式可以省去更換工具的時間,更棒的是,每個人更能夠把自己的工作做的專精,效率又提高了兩成。 [但,小心成為官僚流程] 這樣的流程跑了很久,員工來來去去換了許多次,但都保持一定的高效率。一天,老闆去看工地,發現A 挖玩洞後,C 緊接著把洞補起來填平,老闆生氣的說:『你們在做什麼?B君呢?』 『喔,他今天請假了』A 說。 最後這個笑點看似誇張,但在企業流程卻常見。許多人習慣了只知道follow 流程去做,卻不之所以然,所以很容易鬧出笑話。另一方面企業也常常不重視流程的教育訓練,所以常常空有好流程卻無法發揮最大的效用。

軟體工程與大型整合專案—以WiMAX整合型計畫為例 (3/3)

圖片
Continuous Integration 在討論版本控管時,我們曾經提到WiMAX計畫使用一個輔助工具「 JCIS 」進行持續整合(Continuous Integration)的工作。那麼,為什麼要做持續整合呢?維基百科中對於 持續整合 的理論有些初步的介紹,包含下列十個重要的Practices: 維護一個程式庫(Maintain a code repository) 將建置自動化 (Automate the build) 使建置能進行自我測試(Make the build self-testing) 每人每天送交程式碼(Everyone commits every day) 每次送交都應該被建置(Every commit should be built) 維持快速的建置時間(Keep the build fast) 在實際運行的環境下進行測試(Test in a clone of the production environment) 簡化取得最新可交付版本的方法(Make it easy to get the latest deliverables) 每個人都能看到最新版建置的測試結果(Everyone can see the results of the latest build) 將佈署自動化 (Automate deployment) 上述許多Practices都要求自動化,自動化又可以分為半自動和全自動,以半自動為例,可能是有人每天固定手動執行make指令,將所有要建置的檔案編譯與連結,接著有人將結果複製到實際運行的環境,再下指令讓電腦執行所有的測試,這個過程雖然必須由人來操作,但只要下少許指令就可以完成了。那麼全自動呢?就是在專案開始的時候進行若干設定,之後由電腦自動處理一切編譯、連結、測試等工作,這就需要一套輔助工具了。 要確實完成這麼多的Practices,其實門檻是很高的。即使是在企業界,也難免會有不遵守遊戲規則的軟體工程師,更何況我們的開發主力是學校裡沒什麼專案成敗壓力的學生。舉例說,要做到「每人每天送交程式碼」幾乎是不可能的,基本上學生開發程式是有一天沒一天的,最多只能要求到「有修改就必須送交程式碼」。另外像是「每次送交都應該被建置」,在我們第一年的WiMAX計畫中可以說是完全失敗。在開發環境未能統一的...

無題

趁歲末,我花了一點時間,回憶一些各方對今年發表的諺語與部落格文章所提出的意見,雖然這些意見不能涵蓋全面,但多少反應一些現象,這種現象顯示國內軟工教育問題,就是學校的軟工教育訓練不能完全『 學以致用 』,也讓我這個開授軟工課程多年的教師匠有點『做白工』的感覺,嚴重一點說,有點誤人子弟。 話說,從今年2月20日薛教授post上去的『好人難為』一篇文章,以及最近Q39諺語:『Schedule是用來Delay的』說起,我覺得我們的軟體工程師似乎受很大的委曲,大部分的委曲都是說很難與老闆溝通,有人說溝通無效只好忍氣吞聲,或者默認,甚至乾脆打包走人(「好人難為」意見箱),『‧‧‧要不然抱怨變化永遠趕不上客戶的一通電話』(Q39諺語),甚至說如果客戶來個需求變更,那(專案)就要delay到天荒地老等等,是不是那麼嚴重,我想還不至於吧,不過我相信這些抱屈都是事實,也都是經驗之談,不過從軟工的角度來看,似乎並不希奇,雖然有幾位教授以及本人對這種現象多少有些解釋也提供一點意見,我相信這種現象並非完全無解,重點在於『學以致用』,要致用當然要『百鍊成鋼』,只可惜據我所知,許多學校的軟工訓練並未提供這種機會(包括我自己),例如世界上許多軟工界的『先賢』或『現賢』,提供不少設計軟體的方法(methodologies)、原則(principles)、或樣式(patterns),諸如Agile Methods,Protected Variations及其引伸的OCP、DIP、或Information Hinding等等原則,我不知我們的軟體工程師發展軟體時是否應用到這些『優美』的方法、原則、與樣式?但這些設計原則的確可以解決上述不少問題,我不相信當我們的工程師要應用這些方法‧‧‧時老闆會加以干涉,如果我們的軟體工程界發生這種干涉現象,『軟體工程學會』應該出面解釋甚至說服,學會有責任導正軟體發展的方向,而不是只開開會討論了事,這是我寫這篇不怎麼討喜的短文主要動機。

軟體工程與大型整合專案—以WiMAX整合型計畫為例 (2/3)

圖片
版本控管 在整合國科會CMMI文件與程式開發的過程中,總計劃與各子計畫的文件與程式都需要一個版本管理的機制,一方面萬一有電腦當機或是檔案損毀時,可以迅速還原最新的版本,解決資料備份的問題,另一方面還可以在歷史紀錄中往返,將刪去的文件或程式找回來。對於文件或程式整合而言,版本控管十足是一個Time Machine。 我們在第一年開發之前就已經預期到版本控管的重要性,因此在專案初期便架設可透過Web介面存取的版本控管伺服器(Apache + Subversion),並且安排Subversion的教育訓練。但是,可能是一開始時教育訓練的內容安排不符合需求,也可能是開發團隊不夠用心,導致版本控管並不上軌道。最常發生的問題包括:團隊成員未確實解決衝突(Conflicts)、久久不送交(Commit)程式、送交無法編譯的程式、送交時不寫註解等。 這些問題的原因,有部分與先前討論過的缺乏一致的開發環境有關,部分團隊使用的IDE沒有支援版本控管,所以得在IDE編譯完後才知道有沒有問題,然後再使用其他版本控管軟體(TortoiseSVN等)送交程式;或在Windows上取出(Check out)程式然後複製到Linux的機器上修改與編譯,然後再複製回Windows上覆蓋舊版本後送交,然而在取出後到送交前的這段時間,如果沒有進行更新(Update)和合併(Merge)的動作,這些行為常常會導致衝突。 久而久之,有些團隊成員開始害怕使用版本控管系統,導致送交的週期越來越長,甚至有超過二個禮拜沒有送交程式碼,失去使用版本控管的優點。長時間的修改送交週期,也讓成員忘記曾經修改過什麼東西,自然不知道要寫什麼註解,這些都是讓版本控管失去威力的錯誤行為。經過一整年的觀察後,總計畫在第二年開始前,重新規劃Subversion的使用方式。 首先,我們將版本控管的支援加入一致的開發環境中。在Virtual Machine中,我們使用Eclipse搭配Subclipse套件,讓IDE與版本控管合而為一,之前也提到,單元測試的執行也加到程式中,這些都是確保程式無誤的前置作業。另外,針對文件撰寫的環境(通常是Windows平台),撰寫TortoiseSVN的操作手冊,讓新加入的成員快速進入狀況。 接著,我們訂定幾個需要遵守的原則(Principle),在文件部分,要進行編輯的文件一定要...

軟體工程與大型整合專案—以WiMAX整合型計畫為例 (1/3)

圖片
以往學生在學軟體工程時,總覺得這門課就是在「寫文件」,對於為什麼要寫文件,以及文件的用途,不甚了解,甚至覺得寫文件是很枯燥乏味的一件事。的確,為了交作業而寫文件,我想沒有人會認為寫文件是有用的,特別是對於一個虛擬的軟體專案而言,即使必須開發對應的軟體,充其量也是一個小品,而且一個學期的時間又很有限,所以不是文件品質不好就是軟體沒寫好,更別提要維護了, 而學生無法對軟體跟專案產生情感,自然無法體會文件的意義。 過去三年,筆者因為主持國科會整合型計畫「WiMAX 無線通訊系統軟體與工具開發(I),(II),(III)」的關係,需要主導撰寫其Light-weight CMMI文件,剛開始的第一年,參與計畫的學生們也是哀鴻遍野,學生們即便已經參加過國科會舉辦的Light-weighted CMMI研討會,寫出來的文件,和實際的軟體設計仍有一段很大的落差,一直到第二年,需要開始維護第一年的軟體時,學生才慢慢體會到軟體工程要的不只是文件,而是文件所帶來的價值:溝通與管理。 有一個經常被提到的問題是「軟體流程」?我們的WiMAX整合行計畫到底有多大呢?是否真的需要軟體工程或是完善的軟體流程才能完成呢?這裡先簡單描述一下我們的案子,大家都知道WiMAX被視為M-Taiwan重點發展項目,WiMAX(802.16e)是一個相當複雜的通訊協定,而我們的目標是開發一套完整的「WiMAX網路模擬軟體」,由於WiMAX由上到下包含許多子層,而各子層又各須非常專業的知識,因此,這個案子需要軟體工程加入,才能有效地整合各種跨領域的知識,構成一個完整的系統。也因此我們(北科大軟體研發中心)才提出這個跨領域的整合型計畫,希望開發出WiMAX網路模擬軟體,以開放原始碼的方式貢獻給業界作為WiMAX參考模型,並分享我們的開發經驗。 在WiMAX的案子中分成三個主要項目:「應用」、「協定」與「輔助工具」,應用有「即時視訊傳輸應用」與「適地性資訊服務」;協定負責WiMAX通訊協定的所有子層包含媒體存取控制、安全加密、實體層編碼、實體層調變與通道模擬;輔助工具則提供通訊軟體模型建構工具與持續整合等輔助。由此可知,計畫規模頗大,最多曾經有12個子計畫。軟體流程不能保證專案如期完工,但能用來監控時程與進度,如果沒有流程,進度落後或是超前,都無法掌握,那軟體勢必是無法順利開發與整合的。 有了第一年的...

手機上的物件導向

最近 HTC 出了一款 Android 手機, HTC Hero , 相信3C 迷及 Google 的愛好者都相當注意。我雖然也注意了一陣子,但最近才發現它一直很強調它的 People-centric 的特色-- 就是以人為中心,將電子郵件、通話紀錄、簡訊整合在一起的功能。這樣的設計感覺起來很直覺,很好用。 回頭看看過去的設計,是以通話、傳簡訊、查看通話記錄為主的『功能導向』設計,『人』只是這些動作的參數。這才驚覺原來現在的手機介面設計流行(進化到?)『物件導向』。這樣的進化是偶然?還是從物件設計的理論得到靈感? 如果是後者,也許可以進一步的思考物件設計的技術 -- 例如繼承 -- 如何應用在手機上。 把手機上的聯絡人用繼承樹(a kind of)來模組,如此一來在訊息傳送給父類別的群組時也會送給子類別的聯絡人,或許這樣可以簡化整個手機上的群組關係。當然,物件上的『association』也可以套用在聯絡人的關係的建立。 只是一個突發奇想,可能有點人來瘋。但有興趣的朋友、研究生或許可以試試研究看看。

大長多多

學生們還是問,為什麼需要軟體工程?和程式設計有什麼不同?為什麼需要作專案管理、監控、控管等等?寫得出程式不是比較實在嗎? 這是因為學生寫的程式太小、參與開發的人太少、專案關係人太少、而維護的時間太短,以致於他們無法想像軟體工程的必要性。 真的軟體專案是『大長多多』的。 到了業界,一個專案要破萬行很容易的,程式一旦 大 ,相互關係就會變複雜,動一行指令可能會牽涉到好多地方。所以需要學軟體工程,學如何切模組、作架構設計。學設計概念,知道如何才容易維護、好擴充功能。程式一旦變大,它的成本也會指數性的上升,你需要學習成本估算的方法。 專案的時間通常很 長 ,不是一個星期能完成的家庭作業。所以你需要專案文件(幫助你記憶),專案管理(來掌握時間與分配人力)。維護當然把整個時程拉的更長,所以設計的時候要考慮彈性、成本要把維護算進去。在組織人力調配上,你需要考慮開發與維護是否是同一組人。在這麼長的時間裡,各種不同的版本會產生,你需要版本控管的機制,也需要需求管理來控管變更。 學生的作業多是老師給好的題目,於是很難體會為什麼需要系統分析。業界的專案牽涉的人 多 ,光是『安排』訪談可能就需要一個月。每個人的意見都不一樣,你必須學習一些系統分析的方法來收集、挖掘、歸納、整理、協調、妥協這些需求,再讓這些需求一個個的被所有人確認。除了清楚的腦袋、好的溝通能力、專業技術的判斷,你也需要一些系統分析的方法論。 一個真正系統的完成,需要的專業知識太多,決不是一個人能夠完成的,我們需要很 多 人一起來開發。如何組織這些人?如何分工?是依照<專案管理師、系統分析師、系統設計師、系統工程師、系統測試人員>來切割?還是依據領域來切割?這麼多人合作,版本管理更重要了。組織也需要定一套一致的 coding standard 及 SOP來提升整體的效率。 學校的『小短少少』的環境有時候很難體會軟體工程的重要性。透過專題的製作與建教合作或許有些幫助。

談談設計原則DIP

圖片
3/21本人寫了一篇文章介紹OCP設計原則 (意即:要延伸一個類別時不能要求修改該類別) ,多少引起一些反應,現在我們利用這篇短文來輕鬆談談,另外一項重要的軟體設計原則:「依存反向原則」(Dependency Inversion Principle - DIP)。 首先我們談談何謂軟體「設計原則」,在軟體發展的領域中,所謂設計原則是:「在發展軟體系統的動作中,一種可接受的規則或方法,也就是說可使用的工作原則」( http://dictionary.reference.com/ ),好的設計原則必須是能夠協助發展者產生設計主意(idea),而且可以讓設計者能夠透過設計意涵來思考其實際的設計(Rebecca J. Wirfs-Brock 2009),依據這樣的定義,我們所要談的設計原則是可實地應用的,不過原則並非嚴格的設計規則,有如設計樣式(design patterns)一樣,僅在某種環境中使用,過份使用設計原則,可能會增加程式的負擔與工作量,因此,如果你確定類別的功能將來不致改變,則不一定要去使用設計原則,不過大部分的設計原則,都是將實作(implementation)引藏起來,以保持設計的彈性,如OCP或本文即將介紹的DIP。 DIP的定義可見諸於各類設計樣式的書本或網頁,簡言之就是:『抽象不能依存於細節,而細節必須依存於抽象』(Abstraction shouldn't depend on details. Details should depend on abstraction - Rebecca J. Wirfs-Brock 2009),這是何意?我們舉一個簡單的例子:一家公司顧有許多員工,也就是說公司就必須直接依存於這些員工,以軟體結構語言來說,公司是屬於「高階模組」(high-level module),就是上述DIP定義所謂的「抽象」,而員工則屬於「低階模組」(low-level modeule),也就是定義所說的「細節」,如果公司因業務需要必須增聘具有高強能力或專長的員工(也許稱之為super employee),而沒想到使用DIP,則必須修改複雜的公司模組內容,這種修改將影響公司模組的結構,這樣就違反DIP,如果希望增加任何員工而不想影響到公司模組,DIP告訴我們,可以在公司模組與員工模組之間介入一種「抽象層」(abstract layer...

分、時、天

今天在研討會中聽到一個不錯的比喻。軟體工程度量在國內一直很難推動,這或許與國內對於工程量化的觀念比較不足有關係。這一點可以日常生活中的用語窺得一二, 西方人說『wait a minute』,以『分』為單位 台灣人稱火車慢了為『慢點』,以『小時』為單位 印度人則說『等天』,以『天』為單位 這讓我想起PSP (personal software process)方法要求以 分 為單位來記錄工時,但對於我們的工程師的確是很大的壓力。以我們逢甲資訊處為例,工時的紀錄幾乎都是以小時為單位。這之間的關聯是否為巧合?有趣。

憑空產生的程式碼

最近學生報告了一篇有趣的論文。研究團隊開發了一個系統 CodeConjurer(程式碼魔術師),說的是可以憑空產生的程式碼。你會想,這怎麼可能? 它的原理很簡單,首先各位都知道 google 搜尋引擎可以去找全世界網頁的資料,其實還有許多是針對程式碼的搜尋引擎。例如 Merobase。研究團隊利用 Merobase 到一些 opensouce 的地方(例如 SourceForge)找程式碼,程式設計者只要寫出你想要用的物件的功能(也就是定義他的介面),CodeConjurer 就幫你找出一些可能的軟體元件,你可以進去看裡面的程式碼檢驗是否這就是你要的元件,如果是的話,可以馬上下載並整合到你的專案中。這無疑的可以幫你節省一些時間。 當然,光是透過介面的定義就認定該原始碼就是你要的可能會有些風險。為了進行 semantic check, CodeConjurer 也與 JUnit 作整合,開發者在使用這些元件前應該先透過 JUnit 確認元件的 semantics。 如果這個東西真的可行的話,第一個要擔心可能是老師們,因為抄襲的問題可能會越來越嚴重,學生可能越來越不寫程式。但從軟體工程的角度來看,這不失為是一種 code reuse 的發展趨勢。在防堵學生抄襲的同時,老師們也需要教導如何在有限的時間內套用正確、合適的元件來增加軟體開發的效率。

新書介紹:Inside Steve's Brain

圖片
『如果我問我的顧客想要什麼,他們會回答我一匹跑的更快的馬』- 亨利 福特 最近上了一本新書『 Inside Steve's Brain 』,說的是蘋果賈柏斯對經營、設計的一些理念。我想大家對賈柏斯轟轟烈烈的事蹟一定很熟悉(特別是蘋果迷),在此不做贅述。我個人雖不是蘋果迷,但也深深的佩服他對設計的執著與相關產品的簡約。我一直覺得台灣需要的不是系統實作人才,應是軟體設計人才。設計是什麼?我所說的並不是什麼結構性設計、物件導向設計、架構設計等技術的東西。 而是態度。一種對設計的態度。 什麼是設計的態度?答案也許在這本書中。推薦各位看看。 一般而言,軟體工程裡都教我們系統分析時要做需求訪談,聽顧客的話。但在某個領域中,特別是創新的領域中,傾聽自己內心的渴望(對產品的渴望)是更重要的:我們如何能做出讓人能夠感動的產品?Steve 相當欣賞亨利 福特的一句話:『如果我問我的顧客想要什麼,他們會回答我一匹跑的更快的馬』。 在顧客的框框下,你所開發出來的產品是不會感動人的 ,所以 Steve 在開發產品的時候是不做市調的,這相當有自信且冒險。但對 Steve 而言是行得通的,畢竟能讓一個工作團隊花『六』個月的時間調整一個 scrollbar 的人並不多。

談談OCP

圖片
看到「好人難為」一文,主角是一位專班學生,看來他似乎很委曲,因此我在意見箱內提議,他可以好好研究一下軟體設計的第一原則:Open-Closed Principle (OCP),或許可以解決他的困擾,這件事涉及到軟體工程的教育與訓練的問題,也就是說,學以致用的問題,因此有必要寫一篇短文以OCP為例,來談談軟體設計原則的運用,這些原則並非軟體發展的食譜(cookbook),而是發展者必須放在心裡的「指引」(guideline),這種指引必須落實成為diciplines,其他如設計樣式(design patterns)也具有指引特性,因此才能廣泛運用,也就是說,可以重覆使用(reuse),學習時最好蒐集一些範例,可能有助於這些設計原則或樣式的運用,有如念法律的人必須研究一些判例一樣,學習軟體發展方法時也不例外。 OCP是物件導向方法的核心,1988年由Bertrand Meyer在他的著作" Object-Oriented Software Construction "一書提出,它是說:「軟體實體必須能夠延伸但不能修改」(Software entities should be open for extension but closed for modification),換言之,必要時可以延伸軟體實體的功能但不必修改它,該軟體實體可以是類別、模組、功能、程式、或組件,完全看你用在何處。Meyer的原意是說,類別實作(或程式)除了須要除錯外,如要改變功能或增加新功能時不得改變父類別(superclass),而由子類別(subclass)來達成,子類別可以利用繼承(inheritance)機制重用父類別的屬性或作業元,但可改變或增減其功能,因此繼承不旦可以重用父類別的實作,同時可以延伸原功能,該子類別的介面可以異於父類別的介面,這是一般具有物件導向的人所熟悉的繼承機制。 到1990年代OCP被重新定義為,新介面可以繼承自「抽象類別」,但非繼承實作部分,原介面不得修改,也就是說,你設計的組件或模組不能改變,當需求改變時,你可以增加新程式以延伸該模組的功能,但不能改變你也許認為十分完美而能作業的原程式,請看下圖(R.C. Martin), 左邊圖形表示,如果Client想使用另一個Server時,Client必須改變,因為兩者皆是concrete,這樣就不...

千奇百怪的需求

對開發軟體系統的人而言,最害怕的並不是寫程式,而是千奇百怪的需求。一個朋友告訴我他曾經做過某個學校的校務系統,在加退選的前一天: 『第十五個選課的人不可以退選』學校突然向他們要求這個需求。 經過了解才知道一門課至少必須有十五位選課才可以開課,否則就會倒班,所以校方就提出這個需求。但是用這種方式來預防倒班也有點奇怪。 有趣的事發生了。甲生是第十五個選到課的人(當然他自己不知道他是第十五位),而第十六位選到課的同學正好是他朋友,甲生眼睜睜的看到他同學可以退選,自己卻不能退選。接著又有其他人加選後退選也可以,但他剛好又是第十五位,他還是不能退選,你說氣不氣人? 於是這個問題學生提出來,最後只好把把這個限制拿掉。有時候一個系統的功能看起來沒有幾項,卻是在修修改改之間浪費了很多的時間,如果能夠事先想清楚,是不是可以省很多的時間?如果一個有經驗的系統分析師能夠在顧客提出奇怪的需求時就能跟他們分析這些需求後續可能造成的影響,那就有很大的幫助。

靈感與文件

我自己以前很喜歡寫程式,現在不年輕了就較懶惰,所以大家猜的出來這故事發生在很久很久以前... 一顆1MB的RAM要一千塊美金,而且要排隊一個月才買得到的時代 。 我當初為了一家forwarder/broker(海陸運)公司寫一些應用程式。幫他們架網路,再完成了會計系統、出入口系統等業務的東西,終於要幫Sales的人們開發他們的系統。花了一些時間,把基本需求完成,然後很雞婆的幫他們作了一個小工具。結果,那個小工具成為Sales的人們最喜歡用的功能。 為什麼說雞婆呢?因為這沒有在他們本來的需求裡,而是在某幾次吃飯或咖啡場合聊他們做事的方法,我自己去作一些prototype開發出來的。其實那個功能需要跨幾個資料庫撈一些資料再整合,只是我們當初所使用的資料庫系統會鎖住資料庫,沒辦法邊看邊編輯資料。其實是為了安全的考量,資料庫鎖住是很合理的事。可是為了這限制,我一直沒有辦法完成我想要的功能。最後,在某一次的嘗試中,動態跑到作業系統裡把lock挪掉,做完工作,再把lock搬回,竟然就完成了所期待的工作。雖然有些危險,但是我非常有把握在這些功能的使用範圍內,應該是不會發生任何問題。 事實上,這工具他們之後用了很久,而且沒有發生任何意外。直到有一天我接到越洋電話... 時間已過幾年,我也搬來台灣。原來他們要upgrade系統,再重建構系統,所以希望我說明當初到底用了什麼撇步完成那功能。 坦白說,我連什麼功能都忘了,哪裡記得什麼妙法? 不知道各位有類似的經驗嗎?很多時候拼命coding,不是trial-and-error,就是靠著一些靈感完成工作。然後,沒記下來,過幾天就忘光光了。 明明知道要加註解,可是怎麼可以停下這麼順的『手感』,就繼續code下去了。更不用講到文件了...

好人難為

這是一個專班學生的故事。 他的工作是跟物料管理系統的開發相關。公司用的實作框架中包含一個 tree 的 model。有一天,因為使用者的需求變更,他的上司決定把 tree  model 改掉以快速的解決顧客的問題。他仔細的看了這個方法,知道一定會對後續的成本計算產生問題,因此請主管不要改 tree model。 但是顧客的問題必須要馬上的被解決,所以主管決定還是要改。有軟體工程概念的他,瞭解這個問題的嚴重性,他深深的知道這個東西一改,以後的程式都會以這個基礎下去開發,到最後成本計算穩死無疑,因此堅決不可以改,兩個人於是吵了起來。 其他的組員覺得他很奇怪,沒事為什麼要跟主管過不去,還跟主管吵架。在一個保守的組織中,他的『雞婆』並沒有受到肯定,也沒有人有時間深入瞭解他所說的道理,只是覺得他很『機車』,他只好閉上嘴巴照做。 過了三個月,這個問題浮現了,大家忙得雞飛狗跳。但是,沒有人知道他們所遇到的問題是主管所造成的,也沒有人想到他。大家忙著找一個可以立即解決成本計算錯誤的方法。也許,再把 tree model 亂改一通吧。 大家覺得這個故事有哪些啟示呢?

早點來

這是一個朋友的朋友的故事。 當時他還是一個剛當上PM的年輕工程師,第一個案子就遇到大系統,是一個會計相關的系統。辛苦了兩年系統終於到了收成的時機,但是由於許多的需求一開始沒有說的清楚,客戶不斷的質疑他們功能並不完整,介面也不好用,案子又拖了兩個月都結不案。有一天客戶約他吃飯討論系統功能,他準時赴約。 沒想到客戶劈頭第一句話就說:『怎麼不早點來』?他自認以他的手錶來說是準時的,於是那一場氣氛不太好的飯局並沒有達到共識,雙方不歡而散。 過了幾天客戶又約了吃飯,這次他早了10分鐘。想不到幾個客戶已經坐在那裡喝茶等他了,客戶看了看他,還是說:『怎麼不早點來?』。他心裡悶的很,想到張良的故事。心裡想,我下次提早半個小時來,看你怎麼說。 第三次他提前半個小時來,果然比客戶早些了。在愉快的用餐後準備離開前,客戶起身握著他的手說:『下次再提早來』。他有點震驚,卻也不敢說什麼。回去問他的老前輩,是不是顧客在發什麼神經? 老前輩嘆口氣說:『他的意思是要你提前(錢)來』。年輕的小伙子才恍然大悟。 這自然是不可取的事,卻也說明了軟體驗收的困難。許多細微的地方如果沒有寫清楚、說明白,就等的驗收的時候被刁難吧!所以在定義需求規格的時候,腦袋裡一定要想到『 我怎麼驗收這一項需求 ? 』。 另一方面,一定要有把需求擴大來想的本事,顧客跟你說:『這裡要可以輸入商品名稱』, 不要單純的以為只要用一個 TextArea 放個欄位給使用者輸入就好了,顧客腦袋裡想的是一個『商品管理系統』 ,到時候商品名稱要用點的、用拉的、絕對不會是鍵盤輸入的(輸入有很多種,鍵盤輸入只是其中一種)。所以要跟他確認,千萬不要一廂情願的往容易的方面想。如果他真的要一個『商品管理系統』,那麼就得加錢、加時間、或至少釐清了我們做不到。