驚濤駭浪!台灣軟體業的險境 台灣工廠外移,國力所繫的代工產業 危在旦夕,舉國寄望軟體業勃然興起, 但真相是:軟體業 乩童*亂舞、

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

驚濤駭浪!台灣軟體業的險境 台灣工廠外移,國力所繫的代工產業 危在旦夕,舉國寄望軟體業勃然興起, 但真相是:軟體業乩童*亂舞、神壇遍佈,
第一章 資料結構導論 1-1 資料結構簡介 1-2 認識程式設計 1-3 演算法效能分析 1-4 物件導向程式設計與Java.
Java Programming Hygiene - for DIDC
程設一.
陳維魁 博士 儒林圖書公司 第九章 資料抽象化 陳維魁 博士 儒林圖書公司.
第八章 分析與設計階段 – 物件導向設計(OOD)
Project 2 JMVC code tracing
題目:十六對一多工器 姓名:李國豪 學號:B
程式語言的基礎 Input Output Program 世代 程式語言 第一世代 Machine language 第二世代
程式設計概論 1.1 程式設計概論 程式語言的演進 物件導向程式 程式開發流程 1.2 C++開發工具
軟體原型 (Software Prototyping)
Chapter 1 用VC++撰寫程式 Text book: Ivor Horton.
物件導向程式設計 CH1, CH2.
第一篇 Unix/Linux 操作介面 第 1 章 Unix/Linux 系統概論 第 2 章 開始使用 Unix/Linux
JDK 安裝教學 (for Win7) Soochow University
第1章 認識Arduino.
軟體工程 -物件導向程式設計與UML系統分析實作
驚濤駭浪!台灣軟體業的險境 台灣工廠外移,國力所繫的代工產業 危在旦夕,舉國寄望軟體業勃然興起, 但真相是:軟體業乩童*亂舞、神壇遍佈,
單元3:軟體設計 3-2 順序圖(Sequence Diagrams)
Working with Databases (II) 靜宜大學資管系 楊子青
在NS-2上模擬多個FTP連線,觀察頻寬的變化
R教學 安裝RStudio 羅琪老師.
黄海波 & 陶万山 with contribution by 劳晖
CHT IPv6測試 D-Link Taiwan 友訊科技台灣分公司 TTSS 電信技術支援課 Name:
安裝JDK 安裝Eclipse Eclipse 中文化
PowerPoint + Multimedia Files
Word與PowerPoint的結合 建功國小 陳旻杰 健行國小 張慧如.
Android App簡介及 App Inventor 2體驗 靜宜大學資管系 楊子青
雲端運算的基石(2) 虛擬化技術實作(XP篇─上)
Java 程式設計 講師:FrankLin.
Agile Software Development
Chap3 Linked List 鏈結串列.
電腦攻擊與防禦 使用電腦教室VMware軟體說明.
使用者經驗設計 User Experience Design
PowerCam快速數位教材製作 黃雲龍 NCCU/ NTSU.
大數據與我 4A 陳駿榜.
Topic Introduction—RMI
第一單元 建立java 程式.
基于任务的设计:思路、评价与实施 卫朝霞 西 安 交 通 大 学.
VS.NET 2003 IDE.
建立一 function s (type) 可以用來繪製cyclic-harmonic curves
Chapter 5 Recursion.
Ch20. 計算器 (Mac 版本).
資料結構 Data Structures Fall 2006, 95學年第一學期 Instructor : 陳宗正.
Definition of Trace Function
安裝 / 操作 flashget SOP (以Win 7 作業系統為範例)
指導老師:周建興 老師 開發團隊:吳旻翰、池宗諺 淡江大學電機工程學系 2015/12/11
SAP 架構及前端軟體安裝 Logical View of the SAP System SAP Frontend 7.1安裝與登入
徐迎晓 复旦大学软件学院 实现模型 徐迎晓 复旦大学软件学院.
智慧型手機程式設計 建國科技大學資管系 饒瑞佶 2011年(992).
六年級電腦科 KompoZer w3.dhps.tp.edu.tw.
軟體產業升級的利器 - 敏捷方法 中央大學資工系 陳振炎.
DRC with Calibre 課程名稱:VLSI 報告人:黃家洋 日期: 改版(蔡秉均) 1.
利用 EditorConfig 自訂文字編輯器設定
MiRanda Java Interface v1.0的使用方法
熊博安 嵌入式系統實驗室 國立中正大學資訊工程學系
美感教育概念分享 報告人| 張晏慈.
Parasitics Extraction (PEX) 與 postsimulation(posim)
MultiThread Introduction
介紹Saas 以Office 365為例 組員: 資工四乙何孟修 資工四乙 黃泓勝.
Activity的生命週期: 播放音樂與影片 靜宜大學資管系 楊子青
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
Usage Eclipse 敏捷方法工具介紹 實驗室網站:
Chapter 4 Multi-Threads (多執行緒).
Develop and Build Drives by Visual C++ IDE
JUDGE GIRL 使用介紹 & 常見問題 TAs :
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
CHT IPv6測試 D-Link Taiwan 友訊科技台灣分公司 TTSS 電信技術支援課 Name:
Introduction to Mobile Computing
Presentation transcript:

驚濤駭浪!台灣軟體業的險境 台灣工廠外移,國力所繫的代工產業 危在旦夕,舉國寄望軟體業勃然興起, 但真相是:軟體業 乩童*亂舞、 但真相是:軟體業 乩童*亂舞、 神壇遍佈,導致產業不振!** * 乩童 指軟體工程師不做設計(切割), 自然無法做單元測試,則產品不良; 但,他很快做完,又能demo,善男信 女頂禮膜拜!(主管當年也是乩童!) ** 乩童愈多、愈努力,則產生愈多垃圾

敏捷方法苗圃 座落於: www.AgileMethod.csie.ncu.edu.tw 有歷次敏捷方法研討會投影片、 上課教材 (內有最新資料)、實習教材, 產業體檢問卷、經驗心得, 請鑑賞 !

軟體行銷 vs. 軟體工程 軟體行銷 - 找出利基產品、客戶,經營品牌, 是軟體業最重要的事, 老闆們靈活地全球找商機 - 紅海(既存市場) 或藍海(全新市場)行銷 之後,開發團隊工程師們快速完成高品質產品, 這是軟體工程,才是本課程範圍 有人疾呼: 應行銷某軟體,軟體業就有錢賺 - 混淆議題了!須深沈反省 工程缺失

教材結構 Agile 觀念 談 軟體 文化 溝通 思考 myAgile 方法 擴充極限開發法 的十一個工作程序 範例 詳細 Java 開發的數個例子 附錄 重要文獻 及 C#, C++ 單元測試碼

Agile 觀 念

資訊 與 軟體 資訊 (information)是真實世界中, 物件(object) 與物件之間的關係(relationship)的一種抽象概念(abstraction),而這些概念可由人腦認知及處理 (注意:資訊不是電子的 0,1) 電腦軟體 (computer software) 是一種特別的資訊 (information),用來描述電腦系統設計與實作的解決方案 生產電腦軟體的產業就叫: 軟體業 軟體 (software) 是否僅限電腦軟體? NO! 小說、畫作、舞台劇等,亦是軟體

創新 軟體工程 方法 本課程以創新方法,提升軟體業工程實力 強調 綿密的團隊溝通 (組織心理學*) 並採新的 測試帶動法 (測試驅動開發) 創新 軟體工程 方法 本課程以創新方法,提升軟體業工程實力 強調 綿密的團隊溝通 (組織心理學*) 及專注的個人思考** (認知心理學*) 並採新的 測試帶動法 (測試驅動開發) (Test-driven development,TDD) * 軟體與心理學(如 cognitive informatics) 數學 (如 modal logic) 相關 ** 個人思考是陳教授針對國情而補充的,國外文獻無此

軟體業 文化最重要 法國研究者 Bossavit * 指出: 文化 藏於內心無重量至輕,卻影響至深,所以是軟體業無法承受的輕 例子:鄉間深夜遇紅燈停車–乃是發自內心的文化 擁有這文化 才可永保行車安全 反之 若看到警察才紅燈停車 某次可能因沒停車而釀成車禍 造成無法承受的傷害 * Bossavit,The Unbearable Lightness of Programming ,available at: www.cutter.com

軟體業 文化最重要 (Cont.) Bossavit 指出某軟體公司的文化是: 激情 (passion) 大膽 (daring) 華麗(glamour) 乃 似是而非的文化 因激情 大膽 並不等同勇氣 (courage) 軟體外表華麗 也不等同 程式品質 如抽象層次 模組程度 等

奠定 新的軟體業文化 從前,台灣房子蓋好後常會漏水 -- 需 ”抓漏” 要請技術很好的師傅,用獨門”撇步” 修理漏水,一修再修,住戶很不方便 奠定 新的軟體業文化 從前,台灣房子蓋好後常會漏水 -- 需 ”抓漏” 要請技術很好的師傅,用獨門”撇步” 修理漏水,一修再修,住戶很不方便 為什麼不在當初,就把每段落磚塊的漏水測試做好? 軟體業亦然,不良工作文化形成 之後, 寫好的軟體 ”常漏水”,用戶很不方便 為什麼:不在 當初 就建立正確工作文化, 以 測試來帶動開發 呢? 文化紮根愈早愈好,中學即應進行,大一已遲了

Agile 文化 如:架構設計會議 如:演算法設計 1) 綿密的團隊溝通 團隊成員隨時隨地面對面快速溝通, 2) 專注的個人思考 各成員個人思考每分每秒要專注週密, 如:演算法設計

1) 綿密的團隊溝通 敏捷方法的重點: 透過開發團隊成員綿密的溝通, 使開發團隊能因應 變動 (being able to support change) 這對任何成員都有效,不限資深成員 下面先談各種溝通管道,找出最佳的管道, 再依此設計 辦公室佈置 及 測試帶動的開發方法

Communication Channels 溝通管道 A. Cockburn, Agile Software Development, p Communication Channels 溝通管道 A. Cockburn, Agile Software Development, p.95,Addison-Wesley, 2002.

Communication Channels 溝通管道(Cont.) 上圖上方細線有三點表示三種可提問(Question-and-Answer) 溝通管道: 1.二人傳 E-mail 2.二人通電話 3.二人白板前面對面溝通 (效果最佳) 下方粗線也有三點,但 不可提問 (No Question-Answer): 1.書面文件 (效果最差) 2.錄音帶 3.錄影帶

人際溝通的感覺豐富度(感度) 從面對面溝通(具備十一種感覺,如視覺、聽覺、信任感) 刪減 實質接近感度後 例如 視訊連線 (video link) 刪減 視覺感度後 例如 電話 刪減 聲音感度後 例如 e-mail 刪減 提問感度後 例如 手寫字條 刪減 所有感度後 就是:書面文件 (paper or document) Document communication 文件溝通 效果最差 (傳統軟工用的方式) Face to face communication 面對面溝通 效果最佳 (本課程用的方式)

Face to Face Communication Document Communication 軟體工程 的大進步 Document Communication

Document Communication 真相是: 有軟體公司寫很多文件 -但無人閱讀 且讀後是否了解 達成溝通 - 存疑! 應設計 command file 用於電子檔文件 自動統計 1)文件閱讀時間 2)讀者了解程度 等 當然 完整文件可用於新手訓練 但,典型而簡單的一個專案文件就夠了

知道 溝通管道 (communication channel) 後 談一下 溝通目的 (communication purpose)

溝通目的 依 A. Cockburn 溝通具有三個目的: 1) inform (告知) 告知對方不知想法 2) remind (提示) 提示對方已知想法 3) inspire (激發) 激發彼此不知想法

溝通的三個例子 1) 寫小說 作家常年得各方 inspire 溝通 累積想法 作家會記下小扎 拍照(聽說九把刀隨身帶相機) remind 自己想法 某夜 作家文思泉湧 振筆疾書 書成! 小說送出版商 inform 小說內容 出版商校稿 inform 作家錯字筆誤

溝通的三個例子 (Cont.) 2) 攀岩 這是 A. Cockburn 喜歡舉的例子 攀岩要有體能條件 技術訓練 各式裝備等不是每個人皆可勝任 同理 - 不是每個人皆可勝任軟體工程師 攀岩時絕不可單飛 (類似pair programming) 每向上攀一步 一定要等同伴 inform 安全信號 才可引身向上 否則粉身碎骨

溝通的三個例子 (Cont.) 3) 編排舞台劇 編劇寫出劇本 (是書面文件) 導演閱讀後 深受感動 思潮澎湃 (inform & inspire 溝通) 經無數次與音樂 佈景 演員 開會及彩排 (是面對面溝通 其中不乏拍桌咆哮的溝通) 整個流程中 電話 Email不斷 (remind 溝通) 終於 舞台劇推出 撼動了觀眾的心!

溝通目的 影響文件 依溝通目的的不同 文件須做調整 如讀者經驗豐富 則是remind溝通 文件要精簡 如讀者經驗不足 則是inform 溝通 文件要詳細 因此 為適應多種讀者 文件應有精簡版 並可用 hyperlink 閱讀詳細版 一段 YouTube 影片 是inspire 溝通 有可能激發團隊創意

CMMI *and 敏捷方法 CMMI Level 2 (project management) 有助敏捷方法 須實現之 有助敏捷方法 須實現之 CMMI Levels 3,4,5 (engineering and process management) 則與 敏捷方法 觀點不同** 不應進行之 * Capability maturity model integrated (CMMI) 是美國 CMU 評鑑軟體公司能力的分級制度 ** Sison and Yang, Use of Agile Methods and Practices in the Philippines, Asian Pacific Software Eng. Conf. (APSEC), Nagoya, Japan, 2007.

敏捷方法 減少文件 傳統軟工CMMI採工廠思維:視軟體工程師為被動的工人,故訂出很多考核評量辦法 台灣學生從小應付考試,很被動的 相反的,敏捷方法則:提升為主動負責的人(改造的生命 changed human life), 所以辦法(及相關文件)就消失了 例子: 如要考核 pair programming,則 工程師每天要寫報告,秘書每週做報表,經理每週審閱報表

敏捷方法 減少文件 (Cont.) CMMI 與 極限開發法 (Extreme Programming, XP) 可謂連續光譜的兩個極端 中間是相混合的 隨著人員面對面溝通能力逐漸提升 文件活化簡化了 文件量逐漸減少(決非強制消去文件)專案逐漸由一端 CMMI 轉為另一端 XP 這中間的任何點都是敏捷方法

敏捷方法 減少文件 (Cont.) 這兒有一點要深思: 如果大家只在同一房間不斷溝通 但各人無深入思考 則仍不可能產出優良產品的

Agile Method vs. Agile Process Method 指的是軟工使用的符號 如 Object-oriented (O-O) Method Process 則是執行 method 的方式 如 面對面方式 所以,嚴格說 Agile Process* 才對 但大家習慣稱 Agile Method 本教材也依此 * 歐洲知名的 XP 200X conference 就叫 Agile Processes in Software Engineering and eXtreme Programming.

先進軟體公司 的五個敏捷點 依 A. Cockburn 所見, 愈接近這五點,團隊溝通愈敏捷: 1.開發者同處一室 (可面對面溝通) (一室最多十人) 2.有駐點使用專家 (口頭溝通需求) 3.一個月交貨一次 (以產品與用戶溝通) 4.全自動的迴歸測試(一有變動全面重測) 5.有經驗的開發者 (人的素質最重要)

滲透式溝通 (Osmotic Communication) 在耳可聽、目可視的範圍 (如同處一室), 週遭資訊會潛意識地滲透到人腦,達成溝通,其溝通效果旣深層又自然! 例子:小張老李討論某設計時,反覆提到某些詞彙;小林雖埋首工作,竟不知不覺”學會”了。數週後,小林與他人討論時,脫口而出這些詞彙! 需設牆壁阻絕惡質因素滲透溝通 (如客服中心對話)

美國先進軟體公司 佈置圖 common white board caves

美國先進軟體公司 佈置圖 (Cont.) 上圖分 common 及 cave 兩區: Common 區: 兩人一組,在一台大尺寸螢幕前 工 作 (這叫 pair programming) 各組可目視、交談、溝通 Cave 區: 個人處理e-mail, 電話,閱讀資料等 此外牆上很多白板 white board,供討論用 粗估需20坪,台北市很易設置的,軟體業不 求廠大人眾,求高素質高薪、少人、易溝通

回顧 台灣軟體公司 現場 一個小房間裏面坐著滿臉倦容、神情呆滯 (有可能公司節能,不開冷氣,頭暈腦脹)工作一整天,仍加班中的軟體工程師小林,獨自看著一大疊列印出來,自己也看不太懂的程式碼(別人當然更看不懂啦),喃喃自語: 只要再改這地方,就可消除這可惡的最後一個 BUG! 桌上有多本裝訂精美厚厚的文件,但與程式距離遙遠 三小時後,更悲慘了,BUG 仍在! 夜已深,開始自欺麻醉: 明天一早一定就可解決了! (現場安靜、死氣沈沈) 注意: 像這樣 既沒有溝通, 又思考不清,軟體怎麼可能優質?

觀察、改善現場 1.冷氣電費是小錢,工程師產值是大錢,勿省小錢丟大錢 2.辦公室要便於溝通,非必要勿隔間(要搭配群育訓練) 3.要先寫test code 用工具依序test,則不會困惑 (當然要先設計切割,才能在切面上做test code, 且二人邊討論邊做,現場有點喧嘩,但生氣勃勃、 且流露祥和自在的氣氛) 4.要閱讀虛擬碼,勿讀瑣細難讀的程式碼 5.要用工具瀏覽 hypertext (內含 hyperlink), 勿列印(因無工具輔助搜尋、瀏覽) 6.文件常過時未與程式同步 裝訂本更易過時 7.勿加班,否則第二天很累,第三天更累… 8.勿自欺,久而久之,自豪感消失,倦怠挫折…戰將折翼

比較兩家軟體公司的省思 要進步,就須改變;如本國公司因工程品質差而業務外包他國,吃虧的還是本國畢業生的工作權! 因工資高,台灣自豪的工廠外移低工資國度[劉維公,風格社會,天下雜誌,2006] 前進中國、轉進越南,我叫它: 後工廠時代 留下的人要升級,不要代工、悶著頭拼命; 要敏捷地工作,做精緻精品,才有競爭力! 拼命文化 要轉換成 思辯文化 (如印度)

軟體公司招募什麼人才? 台灣學生從小獨自做作業,禁與同學討論,故群育不彰,不善清晰精準溝通、集思廣益;美育也無,無美感、美學,難成就精品 例子: 巴黎街頭,人人衣著搭色和諧:有色感! 台灣智育重視填鴨、應付考試、以分數定高下, 考試中不做思考、只是快速作答;因此,沒有花時 間,平心靜氣、仔細思考的習慣,故做不出精品 例子: 90分鐘考30題,每題若3分鐘解不出,放棄! 軟體開發本是團隊合作活動,人才首重 群育 ; 尤其是 - 忌招乩童

軟體公司招募什麼人才?(Cont.) 在此網路推平世界、全球競爭的時代, 台灣學生國際觀不足,未與世界接軌 例如:1)大學生怕英文教科書,依靠陳舊而質差的中文翻譯本; 2)研究生無力上網吸收最新英文論文 卻自傲以為:憑拼命苦幹及臨機應變的小聰明可做好工作 所以,軟體開發中,英文能力很重要

開發團隊 公民意識 (群育) 依 A. Cockburn 所見,有下面五點公民意識: 1. 準時與會 Getting to meeting on time 2. 回答問題 Answering questions from other people 3. 看到事情要主動講 Bothering to mention things they notice 4. 遵守程式規定 Following group coding conventions 5. 用程式庫 Using code libraries 注意:無擅長交友,順從他人等, 要勇於表達自我,又能包容異見 服装自由,鼓勵特立獨行

群育 與 溝通 群育不只是願與同事開誠佈公討論 而且要有溝通能力 例子: 郵局行員問寄包裹顧客”要幾天的?” 顧客呆住 溝通失敗了 顧客呆住 溝通失敗了 正確的溝通是: “這包裹三天送到要一百元 七天送到要五十元 你要幾天的?”

兩個弔詭問題 1.台灣資訊教育不錯, 何以無蓬勃軟體業? * 2.台灣硬體業很強,何不發展 搭配硬體的軟體 (嵌入式系統)? * 有人怪罪政府支持不力,或本國市場太小等因素

解答一 台灣資訊教育不錯,何以無蓬勃軟體業? 答: 因大部分開發團隊溝通不良, 大部分開發者思考不密,所以工程困難多, 另外還有行銷(市場)困難- 落後而不自知! 真相: 資工*畢業生辛苦地工作 (常加班) 資管*畢業生辛苦地找工作(大多找不到) *資工不重視軟工;資管著重企管中軟體之應用,無軟工 呼籲: 資訊系大一皆修敏捷方法(含於計概) 資工偏重 Java,C#,C 開發 資管偏重 DB/Ruby/PHP 開發 打造就業力! 另,離散數學教SemanticWeb的Description Logic,會很棒

解答二 台灣硬體業很強,何不發展搭配硬體的軟體(嵌入式系統)? 答: 嵌入式系統需 開發組合語言碼,並考慮底層資源限制 故工作量增大, 答: 嵌入式系統需 開發組合語言碼,並考慮底層資源限制 故工作量增大, 因此溝通要更多,思考要更密, 這豈非難上加難?

解答二 (Cont.) 類似疑問 有人指出: 台灣硬體產業已經做得很好了 接著 要做好軟體產業 陳教授答: 台灣硬體產業是工廠式代工產業(並無發明某創新硬體架構等) 而軟體產業是創意產業 二者本質不同 不相關的 只不過 剛巧電腦軟體要在電腦硬體上執行 使人誤以為相關而已

解答二 (Cont.) 類似疑問 某教授驕傲的指出: 台灣是資訊王國 政府應採購國產系統 而不應考慮外國系統 陳教授答: 台灣確是資訊電子產品大國 (PC Notebook 面板等) 電腦大國 但絕非資訊系統大國 更非軟體大國 台灣軟體一般品質不佳

解答二 (Cont.) 有資深工程師說: 台灣工程師能寫出任何程式 言下頗自滿 陳教授答: 優質軟體的重點在溝通 如釐清需求 易學易用 回應快速 而不在程式本身如何寫

台灣產業文化的省思 近數十年,台灣生產線橫掃全球,從雨傘、自行車、到PC (如鴻海帝國,但金融海嘯中亦受創) 依靠的是: 1) 老闆敏捷回應客户需求, 2) 工頭敏捷run生產線*, 3) 工人則敏捷又拼命** * 張忠謀因賞識台灣工頭,而設台積電於台灣 ** 但長期 傷害員工(如高血壓 肝腎病) 且破壞環境(如二氧化碳 全球暖化) 但,軟體業不是生產線,倒像工藝家聯合工坊,不再需要生產線的敏捷,而需要深層的敏捷: 如何思考深且密 如何溝通快而準

台灣產業文化的省思(Cont.) 例子: 阿拉伯文化產業勃興 杜拜帆船飯店舉世知名, 頂級品質即可頂級收費, 而客源爆滿 杜哈亞運展現文化風華, 直追奧運水準,使得 北京奧運當局一時緊張

台灣產業文化的省思(Cont.) 例子: 電影海角七號震撼市場 創下台幣4.6億空前產值 這應歸功於優秀的編劇導演 演活台灣多元文化及族群 激發市場共鳴 掌握了行銷面 但是 因為細節處理(如服裝考證)不夠精準 即工程面不夠嚴謹 無法獲金馬獎評審青睞 終未獲最佳影片

台灣產業文化的省思(Cont.) 例子: 日月潭涵碧樓房價每晚一萬四千元,法國雜誌曾推薦,是觀光業成功例子 但因理念不同,外國經營團隊撤出,一段時間後,驚傳洗澡水呈土黄色 台灣老闆不知: 維持高品質須要嚴謹步驟,這是很昂貴的,且不可省錢的

台灣產業文化的省思(Cont.) 有軟體公司員工因怕上級責難 而做假文件 應付上級 要有不責難的企業文化 不責難下屬遵行錯誤、落後、無法遵行的規條,以去除造假的存在必要 信任開發團隊會以最有智慧與效率的方法完成任務 不以績效考核逼迫做無意義的事 [中華電信 童欣仁 (Chris)]

台灣產業文化的省思(Cont.) 有軟體公司外行領導內行: 不懂技術只會管理的主管,沒有能力帶領開發團隊 管理階層做後盾,依開發團隊的需要全力支援之,而不是高高在上,訂定並要求無法遵守的規條 在彈性中尋求制度,在制度中仍保有彈性: 以彈性敏捷方法開始,遇共通規律性問題才訂指引,但指引中仍保留實際執行的彈性 [中華電信 童欣仁 (Chris)]

失敗例子 震驚社會且引起國際嘲笑的高鐵售票專案即是失敗專案:國內某知名軟體公司 承包後,自己不開發,轉包IBM, 取得美國陳舊鐵路軟體,加以修改,結果釀成大禍,變成國際笑話 真相是: 台灣是軟體落後國 ,要反省,先承認落後, 才能掌握 後進優勢 後來居上

似成功 實失敗 的例子 2007華航火燒機,全機乘客三分鐘逃離,飛機隨即爆炸。畫面傳及全球,俄國讚為奇蹟 (類似案件他們死數百),華航譽機長為英雄 ..成功例子: 機組員訓練有素、乘客臨危不亂,構成高效率團隊! 真相是: 機組員完全無指揮照顧,乘客爬過座椅,高呼開門,數百人耳聰目明、爭先恐後逃難,原來是台灣人自求多福、拚命求生的一幕,華航文化令人扼腕!

成功例子 澳洲雪梨隧道收費系统: 1.隧道口拍攝通過車輛車牌 2.市民買儲值E-tag(大小像門禁卡)逐次扣款 3.訪客上網設 E-Pass (使用介面簡單) 逐次 由信用卡支出 並用e-mail 通知

逐步改善 溝通要達極限 (extreme) 絕非一步可達 要逐步改善文化及設施, 如 1) 同仁願交談 2) 設交誼區 如 1) 同仁願交談 2) 設交誼區 如 1) 願做設計 2)願做單元測試 3) 安裝 JUnit

以上回顧台灣軟工文化的缺失 下面則簡述敏捷方法帶給全球的 一些軟工新觀念

軟體只有設計 而無施工* 軟體設計圖(用Unified Modeling Language, UML畫出) 像畫家的草稿或作家的章節大綱,目的是便於後續的細部思考:資料結構、演算法、程式碼等(我們用設計草圖、虛擬碼來協助這思考,後敘) 軟體設計圖 不像 橋樑設計圖,它已完成細部思考,已定案,故可交施工部門。此時,因已定案,才可做長期詳細的施工時程及成本的規劃 傳統軟工這方面觀念有誤解,敏捷方法矯正之 * Martin Fowler, From Nothing, to Monumental, to Agile , http://www.martinfowler.com (part of this and next 2 slides)

客户關係 與客户為合作(非合約*)關係**,試想: 某軟體公司以200萬承接某專案;若該軟體很快推出且達到客户期望,客户可能獲利1000萬,如案子砸了,誰吃虧大? 客户! 故聰明的客户願意派出駐點使用專家*** 客户公司可能指定兩人探索需求,找出功能清單,再由其中一人任駐點使用專家 若該軟體分四次交貨,每次付款約50萬 * 目前因客户及軟體公司不是非常成熟,須以合約規範 ** 此時社會高度成熟進步-已達extreme,大不易矣! *** 有時開發團隊去客户端工作,也很好啊!

駐點使用專家 工作忙 1.寫使用情節 (Scenario) 2.與開發者確認使用畫面 3.由使用情節寫驗收測試 4.當某功能完成,即刻執行驗收測試 若某功能有五個使用畫面,每畫面有三狀況 則最多有 3的5次方 243 個 驗收測試

駐點使用專家 軟體有客製型(如某公司銷售系統)或一般型 (如 Microsoft WORD) 前者 客戶要派出駐點使用專家 後者 要指定市場調查者擔任駐點使用專家 總之 駐點使用專家 要負責需求之釐清

駐點使用專家 (Cont.) 使用專家必須反映各種不同使用者的不同使用習慣 例如: 手機操作常未考慮中老年人 手指遲緩 按不到小小的按鈕 使用專家必須反映各種不同使用者的不同使用習慣 例如: 手機操作常未考慮中老年人 手指遲緩 按不到小小的按鈕 近視老花眼 看不清小小的顯示

駐點使用專家 (Cont.) 有業界人士指出 駐點使用專家之經費應正式編入計畫預算 因為這經費比需求文件的經費少 而且有效多了

團隊組織 傳統三層: 1)system analyst (SA), 2)system designer (SD), 3)programmer (PR) 另有 project manager (PM) 現只 designer-programmer 簡稱developer (原來1或2 programmers,改為2 developers in pair-programming; 原來 3或4 改為 2 pairs) 駐點使用專家 取代 SA;溝通簡化,低階 PM 消失;工讀生將 developer 做的 test cases 轉成 test code

團隊組織 (Cont.) 由舊團隊轉型為新團隊時,有一靈魂人物: Coach (教頭) 網路上敏捷方法成功故事、 敏捷方法研討會、敏捷方法顧問 當然,上級及客户支持轉型是先決條件

敏捷方法等於寫程式? 因敏捷方法最後只留下原始碼、測試碼等程式,所以有人誤解為: 只在寫程式 當然不是! 敏捷方法做規劃,但不寫規劃書(planning, but no plan);做設計(CRC),但不寫設計書(sequence diagram, class diagram等)。很多工作(tasks)用面對面溝通加短期文件(白紙白板)即達成了,所以長期留下的只有程式(及驗收測試)

專案經理怎麽不見了? 原有專案經理做: 工作分派、工時計算、預算規劃控制、進度報告,要做不少文件,何以不見了? 原因: 各人主動協調,不需經理指揮 (這超難!) 善用白板溝通,不需太多文件 因駐點客户在現場,不必報告客户了

人際溝通 從社會心理學觀點*:人際溝通有知識的魔咒 (下頁實驗)(The Curse of Knowledge) 以軟工而言:開發者在開發當下擁有知識,但無法想像維修者完全無知識的困境,開發者會誤以為維修者也擁有該知識 本法 myAgile 的 設計草圖 及 虛擬碼 即補捉開發者該知識 再傳播給維修者 * Made to Stick: Why Some Ideas Survive and Others Die), 中譯本:創意黏力學 (觀念溝通學 似為較佳譯名), 大塊文化, 2007, pp. 29-30.

擊節者實驗 1990 Stanford Univ. 心理學博士論文 擊節者拿到紙片上有25首常見歌曲 (如生日快樂) 任選一首 在桌上敲擊節奏給聽者 聽者則根據節奏來猜歌名 擊節者預測 猜中機率 50% (因他知旋律) 但聽者聽到一串敲擊聲 只猜中 2.5% 真相:擊節者很難想像聽者不知旋律的情況, 敲得很累(腦中旋律震耳)也沒用,這形 成魔咒,阻絕溝通 (對方怎可能沒聽出??)

破解 知識的魔咒 人類聽故事 (story)時 不是被動的聽 而是會模擬地理位置 在腦海形成一幅圖畫 用視覺想像場景 (scenario) 有誰在裡面 自己在那兒 想像的焦點是故事過程 而非結果 CRC 就是開發團隊一齊做上述的模擬 可模擬多樣的使用狀況 這可能是敏捷方法的學理根據

破解知識的魔咒 (Cont.) 故事提供抽象文字裡缺乏的情境 所以講故事可破解知識的魔咒 而達成溝通 使用者的故事 (user story) 及 故事的情境 (scenario) 會成為O-O 及敏捷方法中使用者與開發者溝通的利器 是有學理根據的 下列溝通六原則 就以 故事 總其成

觀念溝通六原則 簡單 simple 核心 + 簡潔 意外 unexpected 吸引聽眾注意力 具體 concrete 使每位聽眾聽到同樣訊息 可信 credible 讓聽眾可查證 情緒 emotional 讓聽眾有感覺 故事 stories 讓聽眾心中模擬情境

觀念溝通 實例 1961 甘乃迪總統 提出下面與全國溝通: 在十年內送人登陸月球 並讓他安全返回地球 吻合上述六原則 反之 若當時甘乃迪這樣說: 我們的目標是 靠著高度團結的創新 以及策略指向的太空攻勢 成為太空工業的全球領導者 那麼 溝通很可能會失敗 無法登月成功

觀念溝通 實例 (Cont.) Nordstrom 百貨公司有兩套員工訓練簡報: 1) 超優的客戶服務是業務優勢之主要泉源 2) 有個員工免費給客戶包裝在 Macy (敵對的百貨公司)買的禮物 上述何者深植員工腦海? Ans: 2) 因為是一個簡單,意外的故事

設計原則 傳統軟工依傳統工程設計原則* 力求以最少資源產出最大價值之產品 但大部分軟體不易維修 很多在短期內成昂貴廢棄物 傳統軟工依傳統工程設計原則* 力求以最少資源產出最大價值之產品 但大部分軟體不易維修 很多在短期內成昂貴廢棄物 新思維應是生態設計原則** 使軟體易演化(evolve) 生生不息 無廢棄垃圾 * 合理的設計原則, 漢寶德譯, 1972, The discipline of Design by Roe,Soulis, and Handa. ** 從搖籃到搖籃, 野人出版, 2008, Cradle to Cradle by McDonough and Braungart.

下面,先解釋七個基本觀念 再以這些觀念建構出以溝通周期為基礎的 測試帶動法 陳教授提倡的 myAgile 即是一套 具體可行的 測試帶動法

1.Pair Programming 雙人組開發 兩人配對即時溝通,有點像趣味賽兩人三腳; 加快開發及除錯速度,並激發創意 兩人肩並肩坐電腦前,同時注視螢幕,一人主導(drive),另一人從不同角度思考,即時查核(review),並可隨時交換角色 過程中隨時討論程式細節、做法,並藉由討論、爭辯,找到最佳程式寫法,隨時注意程式撰寫的小錯誤或邏輯錯誤,錯誤發生時則共同除錯, 以降低錯誤率和提高除錯效率 這樣可較快完成較佳成果(Better work in less time), 會帶來工作驕傲感 (pride-in-work)

1.Pair Programming (Cont.) 1)工作驕傲感,即自慢(日語,慢者傲慢也)、自傲、自豪,有助培養強烈企圖心、不服輸鬥志、樂在工作中 在此”後工廠時代”,應揚棄下面工廠思維: 兩人做一事,人力成本太高 兩人整天交頭接耳,一定在混! 此外要培養 2)公民意識(後敍),3)敏銳注意週遭, 4)自發地行動 (act spontaneously), 這四點可使團隊績效臻於顛峰 上述就是 群育,正是台灣教育的弱點之一 例子:[電視骨質藥廣告] 一老一少忙於佈置新店面,古董花瓶不小心被年青人撥倒,老人快步扶住,兩人相視一笑

1.Pair Programming (Cont.) 有程式師很自我 ego,不願與某人配對,應離職; 兩人互不願配對,兩人應離職 草莓族雖不耐操,但較不自私自大、反而較合群 例子:某路邊,中年人轎車亂停, 草莓族青年人機車反而都依照格子停 成員程度有高低,高高配、低低配可收切磋效果; 而高低配則形同教學,無切磋之效 人其實不相等,二人行必有我師(古文三人行不精確) ,配對工作可促成團隊技術提升拉齊,所以: 每個回合(iteration),配不同人 (輪調 rotation) 可在大一計概,開始 pair programming!

1. Pair programming (Cont.) 面對面溝通 效果最佳! 1. 小張、老李 pair programs.(效果最佳) 2. 兩人用不同電腦,但肩併肩 (效果很好) 3. 兩人各據一角,背對背 4. 兩人在相鄰辦公室,有牆隔開 5. 兩人在不同樓層或相鄰大樓 6. 兩人在不同時區的城市 (效果差,有人加裝視訊設備, 叫 distributed pair programming, 效果並不好)

Pair Programming 好處 一個人的邏輯思考上常常會出現漏洞,兩個人的邏輯思考卻可以降低這樣的漏洞發生。Pair programming不僅可以提昇工作上的品質,更可以營造出融洽的工作氣氛,以往的programmer都是一個人撰寫一支程式,遇到問題才與同事間 相互討論的方式來解決,或是自己悶著頭上網找資料或想法;若是採用pair programming 的方式,兩個人可以在討論問題之餘穿插個閒話家常,這樣看似是在浪費時間,但是實際上是可以降低彼此腦部思考的壓力,因為一直想同一件事是容易想不通透的,那何不放下心情來降低腦中的壓力後再來思考,這樣對於事情的進展反而是更有幫助的。 [中央大學研究生 蘇友信 (Silver)]

Rotation in Pair Programming Rotation (輪調) 在 Pair Programming 中很重要 例如本次iteration 張三及李四一組 下次iteration 張三及王五一組 這使各人知識分散至其他所有人 可減低因人員流動而造成的知識流失 極有助於軟體演化(即軟體不斷維修)

Collective Code Ownership 經過上述 Pair Programming 及 rotation 久而久之 團隊成員可大致了解他人寫的程式 甚至可維修他人程式 不畏員工流動了 工作中重用 (reuse) 閱讀他人程式時 可快速主動改善之 而不必知會原作者或上級 使軟體在不知不覺中 不斷提升品質 再搭配測試碼嚴密把關 可確保品質 這形成程式碼不屬於原作者的共有制度 叫做 collective code ownership

2. Re-factoring 重構 程式需不斷更新以符合變動的需求,叫重構 這已超越舊的程式重用(reuse)觀念,需: 1.各人願意去改別人寫的程式;相對的, 高興自己程式被別人改進 (群育訓練) 2.程式人人可懂(設計草圖及虛擬碼解決此事) 3.程式修改後,要週密地重做測試 (test code,JUnit 解決此事) 重構後得新版本,存於版本控制系統 好處:interface不變時,因測試碼保護,開發者勇於大幅度 修改舊程式(重構),使軟體常新; 若interface改了,要重做測試碼

3. Continuous Integration 持續整合 每個public method 寫完,用unit test code(後敘)測完後,數小時內即整合進系統,不拖過夜 (隔夜就忘大半了) ,各個 method 是這樣持續地整合進去, 若某功能的 methods 都齊了,駐點使用專家(後敘)就手動測其驗收測試 這好處是: 以往痛苦的integration phase 不見了;現在,腦筋還記得當天寫該method 的細節,所以很容易整合

4. Simple Design 簡約設計 簡約是任何設計的精髓* 透過CRC會議(後敘)的溝通,想出軟體系統中各class 及其之間的關係: 1) 各class 須呈現簡潔外觀 (interface),與一致的格式 2) classes 之間的關係須: 簡潔(關係不可太多) 平衡(不可呈星狀結構) *設計簡約,質感出眾 [IKEA 桃園店標語] 反映北歐極簡、內斂風格 質感 > 品質 > > 質量

5. Release (交貨) 規劃 由駐點使用專家(後敘)主導的會議 (開發者必參加) 會中決定目前系統功能 (user stories) 要分幾次交貨 (release) 客戶需求不斷變動,故只第一個release 確定,往後releases,日後再修訂,這叫演化(evolve);軟體不斷演化,不再有開發、維修之分,且演化使文件瞬間過時,故本法倡虛擬碼,隨時閱讀了解修改軟體

6. Iteration (回合) 規劃 由開發者主導的會議 (駐點使用專家必參加)會中決定”派工及時程”(後述) 每個回合工作量不同,故其週數不固定,平均為三週*。三週不長,故時程可嚴格控制**,因而取信(甚至感動)客戶 * 石頭閒語網站認為:Ruby/PHP 生產力比Java 快5倍,可2-3天就推出release ** 傳統軟工專案常規劃一年,一年中變動太大,專案經理常無力控制時程

7. 站著開日會 (daily stand-up meeting) 每個工作天,全體開發團隊成員要 站著、圍成一圈,舉行每日會議 要站著,才可長話短說,使會議簡短 要全員,才使資訊直接傳達至每一人 要每日,才使溝通週期縮為一天 (昨日談的事,今日即可當面問)

Communication Cycle 溝通週期 不斷溝通、回饋、檢查、除錯、修改; 幫助人人成長、技術精進 回合規劃 站著 開日會 簡約設計 Pair Programming with On-site Customer 1..N Bugs CYCLE TIME 5 seconds 持續整合 重構 1..N Iterations 3 weeks 交貨規劃 1..N Increments 2 months 增量 增量加 上次交貨 測試碼保護中 1..N Methods 0.5day CYCLE TIME 1 day 喜好度調查 1..N Questions CYCLE TIME 5 seconds (Not in XP)

測試帶動的開發方法 (Test-driven development, TDD) 上面的溝通週期圖中,每個溝通圈走一圈(溝通要快而準),就是一次測試,在週而復始的不斷測試中,優質軟體緩緩開發出來了! 例子: Pair Programming中,小張將 N-1寫成 N, 同伴老李馬上指正,這就是測試 例子: Pair Programming中, 駐點客戶 (on-site customer) 小王要求畫面字體加大,這也是測試 例子: 喜好度調查中, 使用者小林回答對某功能喜好度(1至5,5表最 愛)為: 1 (極不喜愛),這也是測試

測試帶動的開發方法 (Cont.) Test-driven development (TDD) 原本是指 test case, test code, test tool 之使用 在本法中 TDD 擴充其範圍,包含了: 口頭確認 (check) 人工審查 (review) 等 廣義的 test

測試帶動的開發方法 (Cont.) 某愛爾蘭軟體公司*報導這種綿密測試,已使傳統軟工整合測試階段,幾消失無蹤,這得力於O-O,藉繼承及組合旣有class,嚴謹建構新的class 而且,本方法的專案不可能失敗,何也? 失敗專案乃是客戶在付出大筆金錢後,得不到預期效果,而失望、生氣、冒煙 … 而本方法兩個月後就要出貨,如客戶不滿意該貨,因只付出第一期款小錢,通常自認倒霉了事,不致冒煙 * http://www.exoftware.com/

以上介紹 團隊溝通 也就是國外談的敏捷方法 以下簡短談談 個人思考 這是陳教授補充敏捷方法的地方

2) 專注的個人思考 Csikszentmihalyi [tʃɪ:k'sɛntmiha:ɪi] * 是創意研究大師,他說: 創意湧現 (Flow) 產生優質工作(good work) 此時工作極為專注,意志力集中,用心、堅持、獨持,思考深且密,將開發者個人思考推至極限 (extreme) * Csikszentmihalyi, Creativity: From Flow Experience to Good Work, 中大創意研討會, Nov. 29, 2006.

促成創意湧現 的三項條件 What conditions foster flow? 1. 全程各步驟目標明確 There are clear goals every step of the way. 2. 行動有立即回饋 There is immediate feedback to one’s action. 注意:(1)(2)正是測試帶動法的溝通週期 3. 挑戰與技能的平衡 (下圖) There is a balance between challenges and skills. (3)使開發者不斷長進(某員工由A,B,C,D 至 E), 止於至善 E (flow, extreme)

高 D E 焦慮 創意湧現 創意湧現 挑戰 C A 無聊 B 低 技能 高

優質工作 (Good work) 生產性活動(productive activity): 1.滿足工藝水準 (meet the requirements of the craft) 2.有益社會,且獲重視 (socially useful and valued) 3.本身獲益 (personally rewarding)

創意湧現 經驗一 專注幾個點 完全專注、全面投入 創意湧現 經驗一 專注幾個點 完全專注、全面投入 Attention is focused on a limited stimulus field. Full concentration and complete involvement. 例子: 某西洋棋士說: 專注有如呼吸,你從沒想到它 (Concentration is like breathing: you never think of it);專注時,就算屋頂塌了,只要沒打到你,你甚至沒查覺到!

創意湧現 經驗二 不再擔心失敗了 There is freedom from worry about failure. 創意湧現 經驗二 不再擔心失敗了 There is freedom from worry about failure. 例子: 某自行車選手說: 你覺得..沒有東西可阻擋你。你已準備好應付任何事情。不怕任何可能發生的事,真令人振奮!

創意湧現 經驗三 對時間的感覺扭曲了 Sense of time distorted. 例子:某舞者說: 兩件事發生… 創意湧現 經驗三 對時間的感覺扭曲了 Sense of time distorted. 例子:某舞者說: 兩件事發生… (1)練舞後,時間似乎過得很快,時已凌晨一時,我說”喔,幾分鐘前才晚上八點 (2) 可是,當我練舞時,時間好像過得比真正時間來得慢

神清氣爽 才能專注 極限開發法有一實務: 不可加班 (No overtime) *,饒富啟發性: 神清氣爽 才能專注 極限開發法有一實務: 不可加班 (No overtime) *,饒富啟發性: 創意工作要精神飽滿、愉快,才能工作專注,創意湧現,才獲高品質作品;如加班、熬夜,次日精神不濟,品質危矣! 進而,週休二日應徜佯青山綠水或悠遊藝文活動,或好好睡到飽, 充份休息,才能神清氣爽、從容自若 * 但若敷衍應付瞎忙八小時,則不適用此!

創意的重要性 世界有可能從 資訊時代 進入 觀念時代 這時 創意 將是最重要的

創意學* 國內學者賴聲川 以舞台劇**創作經驗 研究創意學 他認為創意來自: 1) 深刻人生經驗帶來的洞察力 這方面叫:靈感 想像力 是感性工作 2) 工程方法(即軟工)的認真執行 並以適當形式呈現 這方面叫:製作 組合力 是理性工作 * 賴聲川,賴聲川的創意學,天下雜誌,2006. **舞台劇與軟體並非不相関,軟體常用的 scenario 即是舞台劇場景

實例 某舞台劇將三個靈感串成故事: 1) 台大醫院五號垂死病人講他的故事 2) 他去法國鄉下古堡看到一幅畫 畫中有中國女子 3) 他去中國上海找尋畫中女子

實例 (Cont.) 上面第二個靈感來自: 某次賴聲川到羅馬看畫展 看到一幅畫 畫中有畫 他當時記下小扎: 故事中可套著故事 這就是他的一個 人生經驗

實例 (Cont.) 各個人生經驗已分別儲存成腦海的檔案 創作時 心自動找檔案串在一起 形成創意 但要慎防: 心受習性蒙敝 而無法串出創意 戲劇是人類 抽象思考 的精華 [飛碟電台 2009春節] 而抽象思考正是軟工的首要工作 值得深思

軟體業例子 1) 小王某次看到某網頁呈現方式 日後用到他的作品 2) 老李讀到某論文的演算法 日後用到他的設計 3) 小林上網搜尋 找到某個API (application program interface) 日後他的程式呼叫之 上述皆基於各人的人生經驗

人生經驗 例子 1)某人參加觀光團 走馬看花 號稱游歷多國還留影為證 但毫無體驗人生經驗不深刻 2)某學生很會應付考試 修課證照無數 但無深入理解體會 無法在工作上用的好 3) 因無英文課 某研究生自高三後很少唸英文 可見英文只是學分 與人生無關 4) 某人喜歡聽英文歌 很投入 所以聽懂歌詞且受感動 這就有了人生經驗

myAgile 方 法

試行團隊 國內軟體公司如有決心*、意志力、專注力,可組 myAgile 試行團隊如下: 1. 一名駐點使用專家 2. 四名軟體工程師,形成兩組 3. 二名兼職工讀生 依前述辦公室佈置,run下面 myAgile 方法 * 依陳教授顧問經驗,老闆有心改變採用新方法,但開發者雖然認真聽課,工作時還是用自己熟悉有把握的舊方法,沒有決心拋棄過去的做法

myAgile 敏捷方法 myAgile 係陳教授運用上述觀念,補充極限開發法 (Extreme Programming, XP)所得 是高度理想性做法,須與業界現行做法磨合,逐步改善 不要妄求一次到位 這方法適用十人以內(含)小團隊, 而全世界很多優質軟體,是小團隊完成的 又,因為大型團隊(如100人)會做組織細分 (organizational breakdown), 所以其底層也是小團隊(如10個10人團隊), 故亦適用之,其上層則需其他管理方法

myAgile 敏捷方法 (11工序) * 0.探索需求 (Exploring requirements) 1.使用情節 (Scenario) 2.驗收測試 (Acceptance test case) 3.架構設計會議 (CRC Session) 4.派工及時程 (Dispatching and Scheduling) 5. 單元測試碼 (Unit test code) * 6.資料結構設計 (Data Structure Design) * 7. 演算法設計 (Algorithm Design) 含設計草圖及虛擬碼 8. 補上程式碼 (Coding) 9.單元測試 (Unit testing) * 10.逆向工程工具 (Reverse Engineering Tool) (* 即陳教授 補充部分 其他為 Extreme Programming 部分)

誠摯的叮嚀 myAgile 十一個工序都 似易實難, 因為其理念與台灣現行方法大不相同, 要扭轉思維、換腦袋,超難! 尤其,若圖反敗為勝,立足國際, 更須用心做好,是難上加難!! 我們已針對每個工序,設計實習課程, 公佈於苗圃網站,敬供參考

myAgile 適用範圍 本法適用 Java, C++, C# 等傳统高階語言 不適用網路時代更高階語言 如標記語言寫出的 ontology, agent

0.探索需求* (Exploring requirements) 1.列出使用者名單, 如電梯資訊裝置案區分: 友善(如殘友) 不管(如文盲) 不友善(如強盜) 2.選取使用者樣本 3.觀察、訪談(2),與之開會 4.開會要充份討論 - 腦力激盪(用左腦語文) 腦力繪圖(用右腦視覺) 以增加想法; 減少語意曖昧、投票過濾 以刪減想法 * Gause and Weinberg, Exploring requirements, 中譯本 從需求到設計, 2007.

0.探索需求 (Cont.) 5.會後得到功能清單,及相關特性、限制、偏好 例如:電梯資訊裝置案 功能 function (如:語音提示樓層) 特性 attribute (如:快速提示上述資訊) 限制 constraint(如:獲得該資訊要少於1.75秒) 偏好 preference(如:上述少於 1秒價值一百萬元, 也許使用者不喜歡語音提示太快 少於0.05秒價值二十萬元) 6.功能分次開發後,做喜好度調查

1.使用情節 (Scenario) 駐廠使用專家 (on-site usage expert) 由簡單而繁雜,由正常(normal)而異常(exceptional), 探索找尋 軟體某功能的各種使用情節(scenario),再切割(partition)找出物件 (object)及物件互動 (object interaction,即method) 形成使用案例(use case) 每個使用情節,用一張A4紙,以鉛筆記錄之,字跡要工整可讀,不可鬼畫符;尤其,阿拉伯數字要慢慢寫字字清晰 例子: 遊戲軟體最簡單的 ”情節一”: 1.看到歡迎畫面 (welcomeScreen) (圖一)* ,輸入密碼(password) 2. 看到主畫面 (mainScreen) (圖二)*,離開系統 * 用鉛筆在A4紙畫出各圖

1.使用情節 (Cont.) 傳統常做 流程圖 (Flow Chart) 它與虛擬碼 (pseudo code) 的抽象層次相同 只是表示法不同 而本法採用虛擬碼 一個虛擬碼會對應多個使用情節 例如虛擬碼中 if then else 對應 if then 及 else 兩個使用情節

駐點使用專家 (On-site usage expert) 駐點使用專家(或叫駐點客户, on-site customer 由客户長期派駐團隊工作。它顛覆傳統,問號很多: 使用者怎願到現場幫我們開發? 使用者程度很低,怎懂電腦,如何一起工作? 但,觀念打通後,需求瓶頸 就消除大半了! 他只要懂需求,不用懂電腦 開發時,駐點專家整天與開發者在一起, 可確保需求精準落實於程式中(尤其是氣氛, 美感,情調等美學價值) 實務上,part time(非full time)亦可,但要 補足溝通功能,如多用Email, 手機(含簡訊)等

2.驗收測試 (Acceptance test case) 待程式開發完成後 即做為測試該功能可否驗收之依據 也就是, 依每一個情節跑程式 如順利跑完,則該情節通過, 即一個 驗收測試 (acceptance test case) 通過 例子: 遊戲軟體最簡單的”驗收測試一”: 看到 welcomeScreen,輸入password JFK2008*後, 看到 mainScreen,點選 Exit,離開系統 * JFK2008 是 exact data,”情節一”無此 data

2.驗收測試 (Cont.) 上述 1)scenario, 2)use case, 3) acceptance test case 三種文件 在敏捷方法中應可合而為一 以簡化文件 此文件還可當維修指引 (maintenance guide): 維修時依scenario 執行軟體 可找到呼叫的 method 再找到source code file中 該method 的header及 pseudo-code 了解後 才去修改 source code

3.架構設計會議 (CRC Session) 真相: 架構設計會議常使用CRC會議:六人以內圍坐(二人亦可,國內單人專案多無切割,兩人先溝通切割系統吧) ,執行前述使用情節,激辯推敲情節中該有那些物件,每物件用小卡片(CRC card) (亦可用A4紙)記錄: 1.Class name (C), 2.要做何事 Responsibility (R),(將轉為 method) 3.要誰合作(即需呼叫誰的 responsibility) 叫 Collaborator (C) 會議後所有 CRC cards 即系統架構(class interfaces),此會議是群體智慧- 腦力激盪,快速溝通 真相: 大型軟體從未在架構師腦袋,而是多個程式師共同擁有

架構設計會議 (Cont.) 1. 對每個功能寫出多個驗收測試(acceptance test cases) 要有那個 object 執行那個 method,接著 又有那個 object 執行那個 method … 直到最後步驟做完 3. 討論中,用一張A4紙記錄一個class及其methods, 並指定專人扮演這class (即CRC) 4. 會後,檢視所有A4紙,並調整之(如某method 應歸屬另 一 class) 即得 class interfaces (軟體架構) 5. 架構定案後,各 method 要寫好 header (method description, parameters, return value, exceptions) 1.parameters 不超過 5 個 2.return value 是一個 object, 但寫出的是其 class 3.原則上禁用 global variables

架構設計會議 (Cont.) CRC 集思廣益切割(partition) 情節 (scenario) 並找出下層物件 (hidden objects) 例如: 張三是位軍人 李四是個土匪某日二人狹路相逢 張三要李四用刀殺了他自己 李四赫然發現自己沒有刀 於是 李四要王五賣刀給他 (hiddenObject,ho) 王五要軍火庫管理員提供刀給他 (ho) 張三看著惨死的李四 想起兩人恩怨情仇 不禁流下熱淚

架構設計會議 (Cont.) class軍人{..}; 軍人 張三; class土匪{.殺(武器,被殺者)};土匪 李四; ..... 李四.殺 (刀, 自己); 王五.賣 (刀,李四); 軍火庫管理員.提供 (刀, 王五);

架構設計會議 (Cont.) 專案如沒做好架構設計,將導至: 物件不吻合客戶觀念,即 O-O 失敗! 同時,因無良好切割,常有太大模組, 無法找到完整單元測試狀況,使品質差。 而且,重擔集中在寫大模組那一人, 無法真正分工,也就無法做到teamwork 又,切割出的class, public method 要寫class interface ,再補充成標頭 (header)

Class Interface 的用處 1. 藉精準命名 class names, method names 捕捉客戶觀念,以落實物件導向(O-O)開發;如客戶不懂這些 names,此時尚未開始寫程式,即已確定 O-O失敗! 2. 可依之分工,多人併行開發各 class, 以加速軟體交貨;高速度交貨很重要 Class interface 補充後成為 class header 內有 method headers

Class Interface Selection Sort 的class interface 如下: public class mySort { /*稍後 data structure 在此 目前不含*/ public mySort (int inputArray[]){ } public int [] sort ( ) { } } // end of mySort method interface

確認 物件 駐點使用專家要確認: 物件是否吻合客戶觀念: 確認 物件 駐點使用專家要確認: 物件是否吻合客戶觀念: 1. 將class names, public method names (英文)列一清單, 刪除底層電腦相關 names,如資料庫class 2.不加任何書面或口頭解釋,將清單給駐點使用專家 3. 專家逐一確認上述 names : 如了解,則打勾;如不清楚,則打X 4. 統計打勾比例,如100 個 names 有 80 個打勾, 則 O-O 是80% 成功!

標頭(header)的重要性 搜尋、閱讀 open source 的標頭,才能重用程式(reuse code);與開發程式(developed code) 相較,它較優質,應優先採用:1)因大眾測試過(可信任), 2)並有效能評估(Big O time estimate) 大量重用程式,小團隊(small project size, team size)能快速完成優質大軟體(big problem size) 開發程式行數(Line of code)無甚意義了

標頭的重要性 (Cont.) 標頭 有點像程式碼的使用手冊 常見一般人使用電氣用品不讀使用手冊 (有時因使用手冊艱澀難讀) 易把東西用壞 修幾次後就不能修了 只好丟棄 很不環保 標頭要寫好 程式碼才能易用易修 才活得長長久久

Method header(標頭) 例子 /* subString * A String object呼叫此 method,傳回一份介於兩個指定的 indexes 的 子字串 * * @param beginIndex –子字串起始的 index (含此 index) * @param endIndex –子字串最後的 index (不含此 index) * @return 由 beginIndex 到 “endIndex 的前一個位置” 的子字串 * @throws IndexOutOfBoundsException – * if beginIndex 是負數 or * beginIndex 大於 endIndex or * endIndex 大於 length() * Time estimate : 演算法設計後,才獲此資訊,如 O (n) * Example: “helloworld”.subString(3,6) ; 傳回結果為 “low” */ public String subString (int beginIndex, int endIndex)

傳統設計方式 資深架構師(architect)花一段時間,獨力完成 class diagram,用 UML 表示,用 Rational Rose 製出文件,局部組成關係如下圖: (輪胎是組成車子的一部分) 車子 輪胎

傳統設計方式 (Cont.) 如果去檢查程式,理應找到: class 輪胎{…} class 車子{輪胎 右前輪=new 輪胎(); …} 對應上面的設計,但 真相是: 那 class diagram 只是架構師個人構想,與程式師想法不同,文件淪為 乩童道具! 基本動作已不確實,較複雜的 design pattern, component 如何落實?

例子:架構師畫的class diagram 吉普車繼承(inherite)車子;1人員使用(use)1吉普車 輪胎 車子

傳統設計方式 (Cont.) class 吉普車 extends 車子 { the extended data and methods} class 車子 {輪胎 右前輪=new 輪胎() …; int 哩程; public boolean 發動 (… ) {…} } class 輪胎 {…} class 人員 {private boolean 車子狀況; public void 駕車 (吉普車 車號) {/*發動該車*/車子狀況 = 車號.發動 (… ); … } 小張=new 人員();老李=new 人員(); 吉普車 車1 = new 吉普車( );吉普車 車2 = new 吉普車( ); 小張.駕車 (車1) ;老李.駕車 (車2) 依物件互動,class diagram 只看到人員、吉普車兩個 classes 並非架構師畫的四個 classes:人員、吉普車 、車子、輪胎 真相是:在開發吉普車時,搜尋標頭才發現可繼承重用之前的車子, 而之前開發車子時,利用組成關係,重用更早之前開發的輪胎 反而,用逆向工程工具則會看到: 四個 classes

傳統設計方式 (Cont.) 例子: 兩個軟體工程師互誇: 小王: 我的O-O 程式有三層繼承 小林: 我的有四層! 誰應加薪? 真相: 通常軟體使用一段時間(如半年)後,客户才會要求延伸原軟體(即繼承) 當然,重用時修改旣有軟體,會有繼承,但不至於三、四層

4.派工及時程 依上述軟體架構 (class interfaces), 各個 class 由團隊成員”認領” 即為派工(真義是: 領工) 由認領本人依本身狀況,估計工作天數,乘公司經驗值寬放係數後,即為時程 每天嚴守時程,精準估算交貨日期,以執行力達成承諾 才能取信、感動客戶* *國興電視”全能住宅改造王”注重生態文化,工匠極致矣 下圖白板上顯示 Mary Ann 回合 的派工資訊

Cockburn, Agile Software Development, p.86, Addison-Wesley, 2002.

派工及時程 (Cont.) Release 交貨 vs. Iteration 回合 只對目前回合(二至四週,平均三週*) 做派工及時程規劃,回合可打出進攻節奏(pace)使團隊威猛快速 (strong heart-beat) 每回合後微調方法(methodology tune-up) 每一至四個月(平均二個月)交貨給客戶** *用Ruby/PHP(而非Java)可縮短時間;用組合語言,則增長 ** 不斷交貨(即演化 evolve),已無開發、維修之分

Release 交貨 Increment 增量 Iteration 回合 約二個月 虛線表示:不確定、可變動 增量 1 增量 2 交貨 1 交貨1 +增量2 =交貨2 約三週 回合 (派工及時程)

5.單元測試碼 (Unit test code) 對某 class 的每個 public method (叫單元 unit)先想出多種測試狀況 (test cases)由簡而繁(最簡如 null input)由正常而異常 (異常exceptions 若 handle 不好,軟體將不好用) 每一狀況寫出輸入 (input) 及預期輸出 (expected output) 叫一個單元測試 (unit test case);再改寫成測試碼 (test code) 相對於他國, 國人工作文化較 急燥、善變、肯拼, 所以更需要做好單元測試碼 做為程式護身符 程式一有維修,即全面重跑測試碼,可確保品質

6.資料結構設計 (Data Structure Design) 對每個 class,要設計這 class 所含的 public methods 共同要用的 data 儘可能設計出 high-level data structure 如tree 而非 low-level data structure 如array 這樣可簡化 演算法設計 使之易於思考

6.資料結構設計 (Cont.) 建議使用Java Collections Framework (JCF) * 含下列三種離散數學觀念及其 classes: 1.List如<1,2,3>: ArrayList, LinkedList 2.Set 如{3,1,2}: TreeSet, HashSet 3.Map 如{1->a,2->b,3->a}: TreeMap, HashMap 另有 Heap, PriorityQueue (以後可能有 Network) JCF method header 有 Big O,使得開發method亦有 Big O 例子: for each i 從1 到 N call TreeSet method with O(logN) end for 即得 O(N logN) * Collins,Data Structures and the Java Collections Framework, McGraw-Hill, 2005.

An Example 例: 從小明家有單行道十公里到小英家 本頁是問題描述 下頁才是設計草圖

adjacencyMap 100 17 29 57 85 95 null hash key value next 68899 小華 小莉 29 57 85 95 null hash key value next 68899 小華 -303674281 小莉 72266597 小明 2390765 小英 2599292 阿偉 15.0 8.3 20.0 14.2 10.0 7.4 to distance next

設計草圖 in Java code protected HashMap <Vertex, LinkedList <neighborDistance> > adjacencyMap; protected Entry 小明; protected neighborDistance 小明小莉;

6.資料結構設計 (Cont.) 資料結構設計與演算法設計互有關連,前者高階 則後者精簡、品質高 目前很多人寫程式,不落實資料結構設計,直接進入演算法設計,甚至直接進入程式設計,其資料結構只用很多基本的陣列 (array) 這使得演算法繁複 導致程式冗長不易閱讀維修

7.演算法設計 (Algorithm Design) 先依資料結構及單元測試,畫出設計草圖 (design sketch)並寫下當時的解題想法,再用英詞中句的虛擬碼 (pseudo code)寫出該想法,此即演算法設計 要依不同抽象層次 (abstraction levels) 由上而下逐層寫出虛擬碼 每層都要 trace test case來debug,即演算法設計 除錯 最下層虛擬碼即演算法,要做時間估算 (time estimate), 若時間太長,如O(n3),則重做資料結構設計 若演算法超過一個畫面,則分割出下層 private method, 這可使演算法清晰呈現 (若只有程式碼,無法呈現演算法) 演算法可投影牆上,做 團隊審查 (group review)

7.演算法設計 (Cont.) 寫出完整虛擬碼,然後耐心地 trace to debug,這工作 似易實難 因為:長年來工作習慣根深蒂固,要寫程式才能思考(趕工不放心時更是如此);寫虛擬碼只是應付上級要求,不習慣在該階層思考。也不會封裝低階data 為高階class,以進行高階思考,當然無法有效做此事 一定要深信本方法威力,才能心平氣和、心思澄靜, 不只無錯,而且有創意、美感

7.演算法設計 (Cont.) 有人指出: 不需寫出虛擬碼 因為Java code 是高階語言 本身即具可讀性 但是 依陳教授經驗: 虛擬碼可提供更簡潔 更高階的了解 可讀性更提升 更有助日後維修

演算法設計 例子 單元: public Entry findSmallest (root) 資料結構: binary search tree 單元測試: input 5; expected output 2 設計草圖: 5 3 6 2 4 虛擬碼: 1.從 root 沿左邊走到底 2.return 該 entry的 element

7. 演算法設計 (Cont.) 先上網找現成演算法,常可找到,可省下不少演算法設計時間 若從open source找到程式碼,那省下更多時間,如自行開發程式碼,因演算法常較差執行速度慢,且程式行數較多開發速度慢 因open source 通常他人用過,有bug會有人報告或訂正,通常不用做單元測試;但必要時,可把reused open source當unit,做 test code 英文要OK,才能讀清楚open source的標頭(當然有些寫不好),正確呼叫使用,並與全球同好討論

7. 演算法設計 (Cont.) 一般人從大一起就直接寫程式 跳過演算法設計 這已是根深蒂固的惡習 要改過 注意: 並非整個系統的演算法都設計好了 才寫程式 否則又陷入傳統 waterfall 模式了

An Example class Adjacency Boolean addEntry (Entry theEntry) Boolean addAdjacency (Entry fromEntry, Entry toEntry, Double distance) EntryList getToEntries (Entry theEntry) void showAllAdjacencies (Entry theEntry) void showNames (EntryList entryList)

An Example (Cont.) public void showAllAdjacencies (Entry theEntry) /** * showAllAdjacencies 顯示所有與 theEntry 相鄰的人名 * * @param theEntry 某個Entry * Time estimate: O(n2) * 例: 若theEntry為小莉,相鄰的人名是 小華 阿偉 小明 */ public void showAllAdjacencies (Entry theEntry) 1. 令 toEntriesList 為 getToEntries(theEntry) 取得的 EntryList 2. if (toEntriesList 不為 null) showNames(toEntriesList),顯示 toEntriesList 各個元素所含的人名 例 小華 阿偉 end if 3. 令 fromEntriesList 為 getfromEntries(theEntry) 取得的 EntryList 4. if (fromEntriesList 不為 null) showNames(fromEntriesList),顯示 fromEntriesList 各個元素所含的人名 例 小明 158

An Example (Cont.) private void showNames (EntryList entryList) /** * showNames 顯示 entryList 各個元素所含的人名 * * @param entryList 例 小華 阿偉 * Time estimate: O(n) */ private void showNames (EntryList entryList) for each i 從 0 到 entryList的元素個數-1 顯示 entryList 第 i 個元素所含的人名 end for 159

8.補上程式碼 (Coding) 將虛擬碼改成註解 (加/* 及 */) 虛擬碼逐行補上對應之程式碼 儘量使程式碼隱蔽,不干擾虛擬碼之閱讀 (常見舊程式難讀、難維修,只好重寫) 本步驟虛擬碼針對 Java, C#,C 程式, 若用Ruby/PHP 程式本身即已易讀, 虛擬碼須寫得更高階

9.單元測試 (Unit testing) 待單元程式(unit, 如一個 Java public method source code) 完成後, 再用工具(如JUnit),自動執行 test code 測試該單元 (unit)

單元測試 例子

10. 逆向工程 工具 利用逆向工程 工具 (如codeLogic*) 10. 逆向工程 工具 利用逆向工程 工具 (如codeLogic*) 需要時,可由程式碼(source file;不含 reused code) 動態產生 class diagram, sequence diagram 等文件,供了解軟體全貌、決定維修那個class及檢查相関classes (為了解軟體全貌,main program 之前也要有標頭:系統描述、重大決策) 此工具並有Zoom-in, Zoom-out 等功能 這有可能敏捷達成 CMMI 一些 process areas 的 goals *http://www.logicexplorers.com/products/codelogic

10. 逆向工程 工具 (Cont.) 一般人常直接 coding source code 這種 source code 輸入逆向工具後 產生的 class diagram 亂七八糟 慘不忍睹 反映出 軟體設計品質低落 的 真相 雖另有工整的 工具畫的 class diagram 但那與 source code 不符 造假的!

myAgile 經驗談 陳教授研一學生試用myAgile 做小軟體, 覺得 CRC, test code, pseudo code 很費時,不甚敏捷。反觀,傳统直接coding 快多了;CMMI 寫文件也還 OK 重點: 1) CRC 使test code可行,確保了品質 2) pseudo code 使變動的需求帶來的重構(refactor) 得以敏捷地做;而在變動需求下,CMMI 文件瞬間過時無用 3) 民主溝通費時但品質高;獨裁快速但危險

myAgile 經驗談 (Cont.) 有一雙人組 (pair) 在一齊維修時 先讀 header 再讀 pseudo code 了解後再修改 Java code 這樣只花 15 分 若直接修 Java code 可能需一小時

myAgile 經驗談 (Cont) 讀者投書指出: 一般行業精密分工使員工專業 引進流程重視紀律以掌握品質 平行作業以壓縮時程 何以為敏捷而反其道而行? 要員工有公民意識 會寫程式會設計會測試 要改他人程式 大家同室同桌同電腦 陳教授回覆: 上述行業是一般工廠式行業 流程固定 變化少 創意少 但是 軟體業不是工廠 所以是不同的

三個 範 例

範例一 Selection Sort Test Code, Design Sketch, Pseudo Code, Maintenance. 本例闡釋: Test Case, Test Code, Design Sketch, Pseudo Code, Maintenance.

Test Case Creating unit test cases Post-condition:數列元素為自然數, 且由小到大排序。 Pre-condition:數列元素為自然數, 可能有以下情形: 1. 數列元素皆不同 2. 所有數列元素皆相同 3. 數列元素部分相同

Test Case (Cont.) 依據以上列舉情形,設計以下test cases: 1. 數列元素皆不同 2. 所有數列元素皆相同 Input:{3,1,4,2} Expected Output:{1,2,3,4} 2. 所有數列元素皆相同 Input:{1,1,1,1} Expected Output:{1,1,1,1} 3. 數列元素部分相同 Input:{2,2,3,1} Expected Output:{1,2,2,3}

Test Code 標頭 (header) /* test code: TestmySort.java source code: mySort.java 張一二 2007.5.1 test case 1: {3,1,4,2} ->{1,2,3,4} test case 2: {1,1,1,1} ->{1,1,1,1} test case 3: {2,2,3,1}-> {1,2,2,3} */ 開發者寫標頭,再交工讀生補上 test code test code, source code 檔名要易記易用易管理

Test Code // Java test code 至於 C#, C++ test code 請參閱附錄 import junit.framework.*; public class TestmySort extends TestCase { public TestmySort(String s) {super(s);} /*處理test cases前,需一致處理*/protected void setUp(){} /*處理 test cases 後動作,如釋放記憶體*/protected void tearDown(){} /*改寫每個test case為public void 名稱“test”開頭的method */ public void testSort() {} }

Test Code (Cont.) // Test Code //Test Case 1:input {3,1,4,2} expected output:{1,2,3,4} public void testSort1() {  /* input為待排序數列,expected為預期結果, result為實際結果*/  int input[] = {3,1,4,2},expected[] = {1,2,3,4}; int result[]; /* new 一個 mySort的物件,傳入參數input */ mySort obj = new mySort(input); /*呼叫sort來排序*/ result = obj.sort(); /* assert實際結果與預期結果是否 equal */ assertEquals (toString(result), toString(expected)); }

Test Code (Cont.) // Test Case 2:input {1,1,1,1} expected output:{1,1,1,1} public void testSort2() { int input[] = {1,1,1,1}, expected[] = {1,1,1,1}, result[]; mySort obj = new mySort(input); result = obj.sort(); assertEquals (toString(result), toString(expected)); } 依此方式,寫出所有 Test Cases 的 Test Code

Test Code (Cont.) 開發test cases 要由簡而繁,且要測異常錯誤狀況,以一個 50行 source code 的unit (method) 來說,若有五個輸入參數,每個假設只有二個狀況 (cases),25=32 cases,每個case寫10行 test code, 即有 320行 test code 所以,test code 行數遠多於 對應的 source code

Why 增加兩種文件? XP 常被批評文件不足,又斟酌台灣國情, 故增加兩種文件: 1. 設計草圖 (design sketch) 寫在白板或白紙,短暫儲存 (目前軟工環境不佳,圖難與程式融合於電子檔) 2. 虛擬碼 (pseudo code) 寫在文字檔 (如Java file) 與程式融合, 長久儲存 與流程圖(flow chart)語意相同

Design Sketch 設計草圖 利用紙、鉛筆、橡皮擦、尺描繪出design sketch

Design Sketch (Cont.) 畫design sketch 後 - 看圖說故事: 故事即 pseudo code 細部設計(上頁右側) Sketch 很人性化,開發者心神負擔 (cognitive load) 小,不易出錯,品質較高 兩人在白板前進行 design sketch, 可充份討論,品質較佳

Design Sketch (Cont.) 各種設計皆始於草圖(sketch), 草圖要”草”(不精確描述 未確定部份), 再逐步思考、決定,趨於精確描述, 可用水紋線表示未確定部分的圖 這樣避免率爾決定,才有深而密的思考 程式師常過早使用精確符號(如程式語言) 過早決定細節, 這就破壞了設計品質

Pseudo code 內文 Pseudo code 內文以「英詞中句」書寫 英詞 (English Term) 就是詞直接以英文表達 (如 class name、method name、variable name等),要精準,須與程式內命名相同 至於「詞」組合成「句」,因國人英文造句能力較弱,故用中文句子,便於快速了解以維修之。例如下面中句含二英詞: 從array [i..N-1] 中找 min , 並換到它的第一個位置

英詞 (English Term) 中句 如果開發者以中文思考 且皆閱讀中文資料則其腦海不易訂出精準英詞 可是程式要以精準英文表達的 此時要找英文較好者 review 英詞

Pseudo code 英詞 命名 Class, object, variable 以名詞命名 class 用大寫開頭 最好複數 (如Desks) object 用單數 最好有冠詞 (如myDesk) 只有一個 object,不致混淆,則省冠詞 如 symbolTable 而非 aSymbolTable Method 以動詞命名,並以參數區別之,如: buy (Desks myDesk) buy (Tables hisTable) 為不同 methods

Pseudo code 英詞 命名 (Cont.) 英詞 要易了解,才記得住 (sticky 黏得緊不脫落 意即不忘記) 請用十秒鐘 默記下面英詞 再寫出: 測驗一: WT0820 Oleogg Crosmioft 測驗二: TW2008 Google Microsoft

Pseudo code 英詞 命名 (Cont.) 上面的英詞 WT0820 TW2008 雖擁有相同字母 但因排列不同 其易記性 (stickiness) 品質差異甚大 TW2008 使讀者聯想到: 1. TAIWAN (TW) 2. 西元2008年 這兩個印象深刻的詞 易了解 因而易記 WT0820 則無此機制 讀者需死背字母順序 所以易忘 不易記得

Pseudo code 結構 1. Sequence 如: 2. Selection 如: 3. Iteration 如: 1.從 array[i..N-1] 中找出 min,且換到它的第一個位置 2.固定此數不再更動 只有1.無2. 時,不構成sequence,故不寫1. 2. Selection 如: if 第 j 個數比 min 所指的數小,then min = j end if 又如 case .. end case 3. Iteration 如: for each j 從 i+1 到 N-1 if 第 j 個數比 min 所指的數小,then min = j end if end for 又如 while .. end while

Pseudo Code 關鍵詞 關鍵詞以外的英詞,必須是 data (或method) names 1. 2. …. if then else end if case end case while end while for each end for ? 存疑部分? //TODO 待補充部分 (尚有?或TODO時 不可coding) 關鍵詞以外的英詞,必須是 data (或method) names

Pseudo Code (Cont.) Pseudo Code 依據下面抽象層次 (abstraction levels) 逐層開發: 1. 抽象層次最高,接近人類思考敘述方式。 2. 抽象層次中等,一半程式一半人類方式。 3. 抽象層次最低,接近程式層次。 且逐層用 test case 手工 trace, 這就是 演算法設計 除錯

演算法 Trace 範例

Trace to Debug (演算法設計 除錯) Trace pseudo code 要精準 如無法trace 則表示pseudo code 有思考不週之處, 絕不可貿然進行 coding, 否則, source code 絕不會 work Trace 要心平氣和,從容自信,要優雅, 不慌亂粗糙,才能精準除錯 (Trace to Debug) source code 將無任何 BUG!

Trace to Debug (Cont.) 認知心理學家指出: 要放鬆(relax)、專注、沉靜,不能焦慮不 安,才能心智暢通,創意湧現 (神經緊繃時,做不到這個的) 不妨泡杯好茶,戴耳機(不妨礙同事)聽音樂 在此 專注 情境下,才能查出: 軟體思考漏洞 (BUG!) 例子:某生 確實 trace Compiler Project 虛擬碼, 使 整個 project 程式無 BUG!

Trace to Debug (Cont.) 請回想: 上次找不到鑰匙的情形 愈著急、愈找不到,氣了一整天 …… 晚餐時,氣消了、認了、算了、放鬆了 突然間 - 想到了!就放在 …… 放鬆而專注 (絕不是鬆懈) - 才能 創意湧現 (Flow)

Trace to Debug (Cont.) Trace不下去時,表示在那特定點思考不清,可即刻尋求他人協助那點 只要問題點明確,他人可快速解答之, 這種溝通甚為 簡短有效 若無 pseudo code,他人縱然有心協助, 也將陷入 source code 泥淖中, 這種溝通 耗時耗力、而無成效

Pseudo Code (Cont.) 1. 最高抽象層次為: 2. 中等抽象層次為: 1. 首先從數列 (array) 中找出 min,並且放到第一個位置,並固定此數不再更動。 2. 再從剩餘數列中,找出 min,並且放到它的第一個位置。 3. 依此方式(repeat),直到(until) 走訪完 array 倒數第二個數。 2. 中等抽象層次為: repeat 1. 從數列 (array)中找出 min,並且放到它的第一個位置,並固定此數不再更動。 2. 繼續走訪剩餘數列 until 走訪到 array 倒數第二個數

Pseudo Code (Cont.) 設計問題:數列與剩餘數列有何關係? 挑戰! 走訪 剩餘數列 就是array 索引 (i)的走訪,所以改成 for loop : i為0時,array[0..N-1] 為數列 i為1時,array[1..N-1] 為剩餘數列 由repeat until 改為 for each: //走訪數列 for each i 從 0 到 N-2 1.從 array[i..N-1] 中找出 min,且換到它的第一個位置 2.固定此數不再更動 end for

Pseudo Code (Cont.) 3. 最低抽象層次為: sort: sort array 成由小而大的順序 for each i 從 0 到 N-2 1.min(最小數的索引)指著array[i..N-1]的第一個數 2.findMin:從 array[i..N-1] 中找出 min for each j 從 i+1 到 N-1 if 第 j 個數比 min 所指的數小,then min = j end if end for 3.把 min 所指的數換到 array[i..N-1]的第一個位置

Coding 開發 Java source code 首先建構一個 Class 叫做 mySort,其 constructor所傳入的參數為 integer 的 input array public class mySort { /* data structure */ private int array []; /*constructor*/ public mySort (int inputArray[]) {/*this array 即傳入的 input array*/this.array = inputArray;} public int[ ] sort ( ){ } }// end of mySort

Coding (Cont.) //if 第 j 個數比 min 所指的數小,then min = j end if //end for /* sort: sort array 成由小而大的順序*/ sort ( ) { // for each i 從 0 到 N-2 for (int i = 0; i < array.length-1; i++) { //1.min(最小數的索引)指著array[i..N-1]的第一個數 int min=i; // 2.findMin:從 array[i..N-1] 中找出 min // for each j 從 i+1 到 N-1 for (int j = i + 1; j < array.length; j++) //if 第 j 個數比 min 所指的數小,then min = j end if if (array[j] < array[min]) min = j; //end for //3.把 min 所指的數換到 array[i..N-1]的第一個位置 swap (i,min);}

活著! 活著! Coding (Cont.) Coding 就是逐行在 pseudo code 後面, 補上對應的 source code 故source code要隱蔽 (以後有工具 PseudoCoder ) 不可阻礙 pseudo code 之畫面呈現 程式才易於閱讀、了解、維修,才是活著, 活著! 活著!

Coding (Cont.) 不是活著的程式無法閱讀、維修,叫:垃圾,這專案已死掉了! 有個嚴肅問題: 小林每月生產垃圾一噸;小王二噸 誰薪水高? 1.小王 因產量兩倍 (故產值兩倍) 2.小林 因垃圾量較少,較環保 3.相同 反正都是垃圾

Coding (Cont.) “swap” method,因無涉解題邏輯,故不需pseudo-coding,可直接 coding 為 private method 又,private method 常重構,故不做 test code /*swap: 交換 i1, i2 所指的數*/ private void swap (int i1, int i2) {int temp = this.array[i1]; this.array[i1] = this.array[i2]; this.array[i2] = temp; }

Unit Testing (Cont.) 用JUnit 其下載網址 http://www.junit.org/index.htm  (a)把 source code: mySort.java test code: TestmySort.java 放同一目錄 (b)在命令列檔案所在目錄鍵入 javac *.java 編譯這兩個檔案     若編譯正確,不會出現錯誤訊息

Unit Testing (Cont.) (c)鍵入 java junit.swingui.TestRunner TestmySort

Unit Testing (Cont.) (d) 結果如下: 所有 Test Cases 通過測試

Unit Testing (Cont.) 假設 test case1 改成: public void testSort1() { int input[] = {3,1,4,2}, expected[] = {2,1,3,4}; //錯了!應是1, 2, 3, 4 int result[]; mySort obj = new mySort(input); result = obj.sort(); assertEquals (toString(result), toString(expected)); }

Unit Testing (Cont.) 重編譯TestmySort,再執行Testing,結果如下: 實際結果是: 1,2,3,4 但 test case 1 中 預期結果是: 2,1,3,4, 比對結果,錯誤!

Unit Testing (Cont.) Test case 1 錯誤 Test case 2 正確 Test case 3 正確

Maintain 範例一 針對 Selection Sort 給予maintenance request : 改為由大排到小 1. 修改 test case code (如input 仍是3142,但 expected output 改為4321) 2.閱讀瞭解 pseudo code , 3.修改 pseudo code 及 對應的 source code, 4. 用unit testing tool 做 testing

Maintained pseudo and source code /* sort: sort array 成由大而小的順序*/ sort ( ) { // for each i 從 0 到 N-2 for (int i = 0; i < array.length-1; i++) { //1.max(最大數的索引)指著array[i..N-1]的第一個數 int max=i; // 2.findMax:從 array[i..N-1] 中找出 max // for each j 從 i+1 到 N-1 for (int j = i + 1; j < array.length; j++) //if 第 j 個數比 max 所指的數大,then max = j end if if (array[j] > array[max]) max = j; //end for //3.把 max 所指的數換到 array[i..N-1]的第一個位置 swap (i,max);}

範例二 Insertion Sort 及其擴充之 範例三 Shell Sort 這兩個範例 皆展示 design sketch, pseudo code, source code.

Insertion Sort Design Sketch

Insertion Sort Pseudo Code public int[] insertionSort() /* 排序 integer array 張一二 2007.5. 1 input 待排序 integer array ouput 已排序 integer array */ 1.for each i從2到N-1,逐一將待排序 插至左邊已排序 array, 使變大之 array[0..i] 保持排序 for each j 從 i 到1 if array[j]<array[j-1] swap二元素,j 向左移 else 已插至定位,離開迴圈 end if end for 2.return array

Insertion Sort source code public int[] insertionSort(){ /*1.for each i從2到N-1,逐一將待排序 插至左邊已排序 array, 使變大之 array[0..i] 保持排序*/ for (int i=0; i<array.length;i++){ /* for each j 從 i 到1 */ for (int j=i; j>0;j--){ /*if array[j]<array[j-1] swap二元素,j 向左移*/ if (array[j]<array[j-1]) swap(j,j-1); /*else 已插至定位,離開迴圈 end if*/else break; } } // end for /*2*/ return array;}

Shell Sort Design Sketch

Shell Sort Design Sketch (cont.) 內心思考,不寫出文件的) 1. increment 2 時,array分為兩個 子陣列: k=1: {9 3 1} k=2: {6 4 2} 分別做 insertion sort 2. 遞迴做 shell sort,每次increment 減半, 直到值為1 (即 insertion sort)

Shell Sort pseudo code end for public int[] shellSort (int increment) 1.for each 子陣列 k 從 1到 increment, 分別做insertion sort for each i 從 2到N-1,逐一插至左邊已排序 array[0..i-1] 使變大之 array[0..i] 保持已排序 for each j 從 i 到1 if array[j]<array[j-1] swap二元素,j 向左移 else 已插至定位,離開迴圈 end if end for 2.遞迴做shell sort,每次increment 減半,直到值為1 3. return array

Shell Sort source code public int[] shellSort (int increment) { /*1.for each 子陣列 k 從 1到 increment, 分別做insertion sort*/ for (int k=1; k<=increment; k++){ /* for each i從2到N-1,逐一 插至左邊已排序 array[0..i-1] 使變大之 array[0..i] 保持已排序 */ for (int i=0; i<array.length; i++){ /* for each j 從 i 到1 */ for (int j=i; j>0; j--){ /*if array[j]<array[j-1] swap二元素,j 向左移*/ if (array[j]<array[j-1]) swap(j,j-1); /* else 已插至定位,離開迴圈 end if*/else break; } } } //end for // end for /*2.遞迴做 shell sort,每次increment 減半,直到值為1*/ if (increment >=1) array=shellSort(increment/2); /*3*/ return array;}

風平浪靜-台灣軟體業 藍海 揚帆! 敏捷(agile)方法以測試帶動開發 (Test-driven development, TDD)軟體品質極佳 除國外重視的溝通 訓練,亦加強 國人不足的思考 (含專注)訓練 – 溝通 及 思考 乃深層基本功– 練功後人人紮實、軟體優質, 迎向創意時代,錢途光明!

1. Extreme Programming (XP) 附 錄

XP Core Practices * 1. Fine scale feedback TestDrivenDevelopment via ProgrammerTests and CustomerTests (were UnitTests & AcceptanceTests) PlanningGame WholeTeam (was OnsiteCustomer) PairProgramming 2. Continuous process rather than batch ContinuousIntegration DesignImprovement (was RefactorMercilessly) SmallReleases

XP Core Practices (Cont.) 3. Shared understanding SimpleDesign (DoSimpleThings, YouArentGonnaNeedIt, OnceAndOnlyOnce, SimplifyVigorously) SystemMetaphor CollectiveCodeOwnership CodingStandard or CodingConventions 4. Programmer welfare SustainablePace (original name: FortyHourWeek) * http://c2.com/cgi/wiki?ExtremeProgrammingCorePractices

XP values [wikipedia] Extreme Programming initially recognized four values in 1999. A new value was added in the second edition of Extreme Programming Explained. The five values are: Communication 溝通 Simplicity 簡約 Feedback 回饋 Courage 勇氣 Respect 尊重 (see next page)

Respect 尊重 The respect value manifests in several ways. Team members respect each other because programmers should never commit changes that break compilation, that make existing unit-tests fail, or that otherwise delay the work of their peers. Members respect their work by always striving for high quality and seeking for the best design for the solution at hand through refactoring. Adopting four earlier values led to respect gained from others in team. Nobody on the team should feel unappreciated or ignored. This ensures high level of motivation and encourages loyalty toward the team, and the goal of the project. This value is very dependent upon the other values, and is very much oriented toward people in a team.

When and Why “Agile” was Coined In 2001 in Utah, ”agile” was coined by the Agile Alliance to stress importance of: being able to respond to changing requirements within the project time frame. “Lightweight” was not adopted because it was regarded as too much of a reaction against something (“heavyweight”), and not enough of a belief in something.

Agile Method Values 1) Individual and interactions over processes and tools. 2) Working software over comprehensive documentation. 3) Customer collaboration over contract negotiation. 4) Responding to change over following a plan.

2.C# Unit Testing 3.C++ Unit Testing 附 錄

1. C# Unit Testing // C# test code using NUnit.Framework; /*建立一個TestmySort Class為測試的Class*/ [TestFixture] public class TestmySort { /*改寫每一個TestCase為一個public method,並加上[Test]*/ [Test] public void testCase1(){} }

C# Unit Testing (Cont.) //Test Code //Test Case 1:input {3,1,4,2} expected output:{1,2,3,4} [Test] public void testCase1(){ /* input為待排序數列,expected為預期結果, result為實際結果* / int[] input={3,1,4,2}; int[] excepted={1,2,3,4}; int[] result=new int[4]; /* new 一個 mySort的物件,傳入參數input */ mySort obj= new mySort(input); /*呼叫sort來排序*/ result=obj.Sort(); /* assert實際結果與預期結果是否 equal */ Assert.AreEqual(result,excepted); }

C# Unit Testing (Cont.) Test Case 2:input {1,1,1,1} expected output:{1,1,1,1} [Test] public void testCase2(){ int[] input={1,1,1,1}; int[] excepted={1,1,1,1}; int[] result=new int[4]; mySort obj= new mySort(input); result=obj.Sort(); Assert.AreEqual(result,excepted);} 依此方式寫出所有 Test Cases 的 Test Code

C# Unit Testing (Cont.) 取得與安裝UltraEdit 下載點:http://ape.csie.ncu.edu.tw/cuedit920a.exe 下載完後得到cuedit920a.exe檔,執行該檔案進行安裝

C# Unit Testing (Cont.) 安裝完成後執行UltraEdit,點選輸入授權號碼 使用者名稱輸入 Universal User 授權碼輸入

C# Unit Testing (Cont.) Testing (使用NUnit) 下載網址:http://www.nunit.org/index.php?p=download (a)設定 UltraEdit 環境 選擇 進階>工具組態 指令列輸入csc /t:library /r:(安裝路徑)\bin\nunit.framework.dll %n%e 工作目錄輸入 %p 名稱輸入 NUnitC#

C# Unit Testing (Cont.) (b)將mySort與TestmySort編輯在同一個檔案中(mySort.cs), 並選擇 進階>NUnitC#,進行編譯,產生mySort.dll檔案

C# Unit Testing (Cont.) (c)開啟NUnit圖形介面,並選擇File>open 開啟mySort.dll檔案 TestmySort class 中包含的 TestCases

C# Unit Testing (Cont.) (d)選擇TestmySort ,並點選Run執行Testing 綠色表示測試通過

C# Unit Testing (Cont.) 如果將TestCase改寫產生錯誤,會顯示紅色,並產生錯誤訊息

2. C++ Unit Testing // C++ test code #include <cppunit/extensions/HelperMacros.h> /*建立mySortTest class*/ class mySortTest : public CppUnit::TestFixture{ CPPUNIT_TEST_SUITE( mySortTest ); /*將test case加入testsuite中*/ CPPUNIT_TEST( testCase1 ); CPPUNIT_TEST_SUITE_END(); public: void setUp(); void tearDown(); protected: /*撰寫testcase成為一個 test method*/ void testCase1();}

C++ Unit Testing (Cont.) Test Code Test Case 1:input {3,1,4,2} expected output:{1,2,3,4} void mySortTest::testCase1(){ /* input為待排序數列,expected為預期結果, result為實際結果* / int input[]={3,1,4,2}; int excepted[]={1,2,3,4}; int * result; /* new 一個 mySort的物件,傳入參數input */ mySort obj(input); /*呼叫sort來排序*/ result=obj.Sort(); /* assert實際結果與預期結果是否 equal */ for (int i=0;i<Length;i++) CPPUNIT_ASSERT(*(result+i)==excepted[i]);}

C++ Unit Testing (Cont.) Test Case 2:input {1,1,1,1} expected output:{1,1,1,1} void mySortTest::testCase2(){ int input[]={1,1,1,1};int excepted[]={1,1,1,1};int *result; mySort obj(input); result=obj.Sort(); for (int i=0;i<Length;i++) CPPUNIT_ASSERT(*(result+i)==excepted[i]); } 依此方式寫出所有 Test Cases 的 Test Code

C++ Unit Testing (Cont.) Testing (使用CPPUnit) 下載網址:http://sourceforge.net/projects/cppunit 下載完成後,解壓縮至C:\CppUnit目錄下 開啟Visual Studio 6.0,選擇File>open 開啟C:\CppUnit\cppunit-1.10.2\src\CppUnitLibraries.dsw檔案 選擇Batch Build,並在Batch Build Dialog中選擇all projects,按下Build按鈕

C++ Unit Testing (Cont.) 建立一個MFC AppWizard (exe) Project ProjectName 輸入 CppUnitGUI

C++ Unit Testing (Cont.) 選擇 Dialog based

C++ Unit Testing (Cont.) 只選擇 3D controls

C++ Unit Testing (Cont.) 維持原設定,按下Finish按鈕

C++ Unit Testing (Cont.) 選擇 Project>Settings 選擇 C/C++ tab,Category 選擇C++ Language, 勾選Enable Run-Time Type Information (RTTI)

C++ Unit Testing (Cont.) Category 選擇 Code Generation Use run-time library 選擇 Debug Multithreaded DLL

C++ Unit Testing (Cont.) Category 選擇 Precompiled Headers 點選 Not using precompiled headers

C++ Unit Testing (Cont.) Category 選擇 Preprocessor Additional include directories 輸入 C:\CppUnit\cppunit-1.10.2\include

C++ Unit Testing (Cont.) 選擇 Link tab Object/library modules 輸入 ”C:\CppUnit\cppunit-1.10.2\lib\cppunitd.lib” “C:\CppUnit\cppunit-1.10.2\lib\testrunnerd.lib”

C++ Unit Testing (Cont.) 選擇 Post-build step tab Post-build description 輸入 Copying TestRunner DLL To Build Folder Post-build command(s) 加入 copy "D:\CppUnit v1.10.2\lib\testrunnerd.dll" $(OutDir)

C++ Unit Testing (Cont.) 選擇Tools>Options,選擇 Directories tab Show directories for 選擇 Include files Directories list 下加入 C:\CppUnit\cppunit-1.10.2\include

C++ Unit Testing (Cont.) Show directories for 選擇 Library files Directories list 下加入 C:\CppUnit\cppunit-1.10.2\lib

C++ Unit Testing (Cont.) Show directories for 選擇 Source files Directories list 下加入 C:\CppUnit\cppunit-1.10.2\src\cppunit

C++ Unit Testing (Cont.) 開啟CppUnitGUI.cpp,修改如下: 在開頭的地方加入 #include <cppunit/ui/mfc/TestRunner.h> #include <cppunit/extensions/TestFactoryRegistry.h> static AFX_EXTENSION_MODULE extTestRunner; 在BOOL CMainApp::InitInstance() 中 加入程式碼 CppUnit::MfcUi::TestRunner runner; runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() ); runner.run(); 將下面程式註解起來或刪除     /*   CCppUnitGUIDemoDlg dlg;  m_pMainWnd = &dlg;   int nResponse = dlg.DoModal();   if (nResponse == IDOK) { }   else if (nResponse == IDCANCEL) { } */

C++ Unit Testing (Cont.) 環境與專案設定完成,新增兩個檔案(mySort與mySortTest)將程式碼輸入完成,並編譯執行測試如下: 測試完後 顯示綠色 表示沒錯誤 TestCase 個數

C++ Unit Testing (Cont.) 將TestCase改寫產生錯誤,會顯示紅色與錯誤訊息