Presentation is loading. Please wait.

Presentation is loading. Please wait.

軟體產業升級的利器 - 敏捷方法 中央大學資工系 陳振炎.

Similar presentations


Presentation on theme: "軟體產業升級的利器 - 敏捷方法 中央大學資工系 陳振炎."— Presentation transcript:

1 軟體產業升級的利器 - 敏捷方法 中央大學資工系 陳振炎

2 緣由 產業未升級 使得台灣員工薪資低 觀念未更新 使得產業無力升級 所以軟體業要推動新觀念: 敏捷方法 全面從教育入手 跨校推動 (目前五校參與) 學習本課程後 使產品提升品質 進而使員工快樂又高薪 根絕學用落差

3 做法 一個方法 myAgile (Extreme Programming plus) 一個專案 Grade System (成績系統)
一個網站 Agile Taiwan (台灣敏捷方法苗圃) 今天談: myAgile方法 Grade System Project

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

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

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

7 觀察、改善現場 1.辦公室要便於溝通,非必要勿隔間 2.要先寫test code 用工具依序test,則不會困惑
且二人邊討論邊做,現場有點喧嘩,但生氣勃勃、 且流露 祥和自在 專注自信的氣氛) 3.要閱讀虛擬碼,手動trace之,勿讀瑣細難讀的程式碼 4.要用工具瀏覽 hypertext (內含 hyperlink), 勿列印(因無工具輔助搜尋、瀏覽) 5.文件常過時未與程式同步 裝訂本更易過時 6.勿加班,否則第二天很累,第三天更累… 7.勿自欺,久而久之,自豪感消失,倦怠挫折…戰將折翼!!

8 兩家軟體公司的省思 要進步就須改變,如本國軟體公司因 工程品質差 而業務外包 他國,吃虧的還是本國畢業生的就業權!
台灣不要代工,不要埋頭拼命趕工,不要處處省錢 cost down 要投資升級 cost up, value up,要豪氣做時尚精品 要敏捷工作不斷溝通,要心平氣和,慢活,慢食,深眠 趕工文化 要提升為 敏捷文化

9 測試帶動的開發方法 (Test-driven development, TDD)
每次溝通(溝通要快而準),就是一次測試,在週而復始的不斷測試中,優質軟體緩緩開發出來了! 例子: Pair Programming中,小張將 N-1寫成 N, 同伴老李馬上指正,這就是測試 例子: Pair Programming中, 駐點客戶小王要求畫面 字體加大,這也是測試

10 myAgile 方法

11 myAgile 重點 需求工程 (Step 0, 1, 2 see next page) myAgile 由簡而繁寫多個 驗收cases 比傳統軟工只寫一個case 更為加強 架構設計 (Step 3, 4, 5, 6) myAgile 採用 XP 的 CRC 快速做架構設計 又用 逆向工程工具自動獲得設計圖 免畫圖. 細部設計 (Step 7, 8, 9, 10) myAgile 採用 design sketch, pseudo-code 相當細緻

12 myAgile 敏捷方法 (11道工序) (+補充工序, * 加強工序 , 另外即 XP 原工序)
+ 0.探索需求 (Exploring requirements) * 1.使用情節 (Scenario) * 2. 使用手冊及驗收測試案例 (User manual & Acceptance test case) + 3.架構設計會議 (CRC session) + 4.逆向工程工具 (Reverse Engineering Tool) 5.派工及時程 (Dispatching and Scheduling) 6. 單元測試碼 (Unit test code) + 7.資料結構設計 (Data Structure Design) + 8. 演算法設計 (Algorithm Design) 含設計草圖及虛擬碼 9. 補上程式碼 (Coding) 10.單元及驗收測試 (Unit & Acceptance testing)

13 1.使用情節 (Scenario) 駐點客戶逐步用文字寫軟體某功能 ( feature) 的使用情節(scenario),用A4紙以鉛筆記錄之,字跡工整可讀,不可鬼畫符;阿拉伯數字要慢寫清晰 探索找尋各種使用情節 - 由簡單而繁雜,由正常(normal)而異常(exceptional),內容盡量不重複以精簡文件 同類 scenarios 存放同file ,可用editor快速修改 例子: 遊戲軟體最簡單的 ”使用情節一”: 1.看到welcomeScreen ,輸入password 2. 看到 mainScreen ,離開系統

14 2. 驗收測試案例及使用手冊 (Acceptance test case & User Manual)
例子: 遊戲軟體最簡單的”驗收測試一”: 1.看到 welcomeScreen輸入password CHEN123, 2. 看到 mainScreen,點選 Exit,離開系統 上面 CHEN123 及 Exit 是 輸入資料 welcomeScreen mainScree 是 輸出資料 案例開發後,歸納重要畫面編成簡易使用手冊 便於客戶迅速了解系統

15 3.架構設計會議 (CRC Session) CRC(Class,Responsibility, Collaborator)會議:
四人圍坐,執行驗收測試案例,推敲切割(partition), 找出物件(object)及物件互動(object interaction,即method),須含下層的合作物件, 每張CRC 卡片(可用A4紙) 記錄: 1.Class name (C), 2.要做何事 Responsibility (R),(將轉為 method) 3.要誰合作(即需呼叫誰的 responsibility) 叫 Collaborator (C) 會議後所有 CRC cards 即系統架構設計, 此會議是群體智慧- 腦力激盪,快速溝通

16 架構設計 例子 CRC會議 執行下面驗收測試案例, 找出物件(如張三李四)及物件互動(如捉拿), 並找出user看不到的下層物件(如王五)
架構設計 例子 CRC會議 執行下面驗收測試案例, 找出物件(如張三李四)及物件互動(如捉拿), 並找出user看不到的下層物件(如王五) 張三是位官兵 李四是個土匪 張三要用繩子 捉拿 李四 李四問王五綁何處 (王五是位醫生) *一般英文書用John, Mary為物件名, 國人感受不深, 故用張三等 **直覺的說: 張三用繩子捉拿李四 但 O-O程式不是這樣執行的 method捉拿屬於土匪

17 架構設計 例子 class官兵{..}; 官兵 張三; class土匪{.捉拿(工具)}; 土匪 李四;
架構設計 例子 由上述 可得下列設計: class官兵{..}; 官兵 張三; class土匪{.捉拿(工具)}; 土匪 李四; class醫生{..綁何處 ( )}; 醫生 王五; ..... 李四.捉拿(繩子); …… 綁處 = 王五.綁何處 ( );

18 藉精準命名 class names及其method names
合稱 (class interface) 我們可精準捕捉客 戶觀念,這才落實物件導向(O-O)開發 如果客戶不懂這些 names,此時雖尚未開始 寫程式,但已確定 O-O失敗! class interface 要補上 class header 其內要補上 method headers 註解說明之

19 Class Interface 例子 public class mySort {
/* data structure 在此 (稍後才開發)*/ public mySort (int inputArray[]){ } public int [] sort ( ) { } } // end of mySort method interface

20 Method Header(標頭) 例子 /* method subString * A String object呼叫此 method,傳回介於兩個 indexes 之間的子字串 * beginIndex 子字串起始的 index (含此 index) endIndex 子字串最後的 index (不含此 index) 由 beginIndex 到 “endIndex 的前一個位置” 的子字串 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)

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

22 工序一至三 例子 工序是前後聯貫的 例如: 1.Scenario: show finish message (msg) 2.Acceptance test case: show finish message (msg) “結束了” 3.Architecture design: /* show finish message “結束了” */ public void showFinishMsg()

23 4. 逆向工程 工具 利用逆向工程工具 eUML2 可由程式碼(source file;不含 reused code) 動態產生 class diagram, sequence diagram 等設計圖 這工具提供維修時 快速了解軟體全貌、決定維修那 些classes 及檢查相關的classes 從工序3.架構設計會議後 即可隨時使用此工具產生 設計圖

24 Class diagrams generated by tool

25 軟體設計的省思 例子: 兩個軟體工程師風格迥異: 小王: 某程式寫二百行很快寫完 小林: 上網查API直接reuse 一行也沒寫 誰應加薪? 真相: 小林應加薪 因reused code不需測試 且日後永不需維修

26 軟體設計的省思 例子: 兩個軟體工程師風格迥異: 小王: 很快開發完20K的class 小林: 仔細推敲不同切割方式 最後完成 多個 2K 的小classes 誰應加薪? 真相: 小林 他完成精品軟體 而小王只完成可用軟體

27 5.派工及時程 依上述軟體架構 (class interfaces), 各個 class 由團隊某兩人pair認領
即為派工 (真義是:領工) 由認領 pair 依本身狀況,估計工作天數,乘上寬放係數後,即為時程,寫在白板上,每天檢查時程,即可精準交貨,達成承諾 ,才能取信感動客戶 此即敏捷方法的專案管理 (約三週)

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

29 6.單元測試碼 (Unit test code) 對某 class 的每個 method (叫單元 unit)
先想出多種測試狀況 (test cases) 由簡而繁(最簡如 null input) 由正常(normal)而異常(exceptional) (異常若 handle 不好,軟體將不好用) 每一狀況分別寫出其 輸入 (input) 及預期輸出 (expected output) 這叫一個單元測試案例 (unit test case); 再寫成單元測試碼 (unit test code)

30 單元測試碼 例子 //Test Case 1:input {3,1,4,2} expected output:{1,2,3,4}
單元測試碼 例子 //Test Case 1:input {3,1,4,2} expected output:{1,2,3,4} public void sortTest1() {  /* input為待排序數列,expected為預期結果, actual為實際結果*/  int input[] = {3,1,4,2},expected[] = {1,2,3,4}; int actual[]; /* new 一個 mySort的物件,傳入參數input */ mySort obj = new mySort(input); /*呼叫sort來排序 其實際結果存入actual*/ actual = obj.sort(); /* assert實際結果與預期結果是否 equal */ assertEquals (toString(actual), toString(expected)); }

31 //Test Case 1: input {3,1,4,2} expected output:{1,2,3,4} //Test Case 2: input {1,1,1,1} expected output:{1,1,1,1} //Test Case 3: input {3,2,4,2} expected output:{2,2,3,4} public void sortTest1() { /* input為待排序數列,expected為預期結果, actual為實際結果*/ int input[] = {3,1,4,2},expected[] = {1,2,3,4}; int actual[]; …….. public void sortTest2() { …… public void sortTest3() { ………

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

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

34 資料結構 設計 例子 開發 findMin(): 找a,b,c等10000個 elements 的最小值 1.資料結構如用array 則演算法為: 令min為array第一個元素 for each array元素 if 它比min小 then 令min為它 end for 2.資料結構如用 min-heap 則演算法更簡單: 3.如無資料結構,則無演算法: 令min為a if b比min小 then 令min為b if c比min小 then 令min為c 這要寫( )行程式 不可思議!

35

36

37

38 8.演算法設計 (Algorithm Design)
先依資料結構及單元測試資料, 畫出設計草圖 (design sketch)並想出解題想法, 再用英詞中句虛擬碼 (pseudo code)寫出該想法 要依不同抽象層次 由上而下逐層寫出虛擬碼 每層都要 trace to debug,即演算法 除錯 最下層虛擬碼即演算法 (algorithm),要做時間估算 (time estimate), 若時間太長,如O(n3),則重做資料結構設計

39 SORT Design Sketch 利用紙、鉛筆、橡皮擦、尺描繪出design sketch
首先從數列中 select 出 min(即 數值 1),並放到數列的第一個位置(即 索引 0)。 索引 數值 .. n-2 n-1 3 1 4 2 1 ( i ) .. .. n-2 n-1 1 3 4 2 固定此數不再變動。 再從剩餘數列中 select 出 min(即 數值 2),並放到剩餘數列(即 索引 1 ~ n-1)的 第一個位置 (即 索引 1)。 1 ( i ) .. .. n-2 n-1 1 3 4 2 .. n-2 ( i ) n-1 1 2 4 3 固定此數不再變動。 依此方式直到走訪完, 走訪至數列倒數第二個數(即 索引 n-2)。 .. n-2 n-1 1 2 3 4 即完成數列小到大sort

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

41 SORT Algorithm for i from 0 upto N-2
1.min(最小數的索引)指著array[i..N-1]的第一個位置 (即array[i]) 2.從 array[i..N-1] 中select出 min for j from i+1 upto N-1 if 第 j 個數比 min 所指的數小then 叫它min end if end for 3.把 min 所指的數換到 array[i..N-1]的第一個位置

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

43 英詞 命名 Class, object, variable 以名詞命名 class 用大寫開頭 最好複數 (如Desks)
object 用單數 最好有冠詞 (如myDesk) 只有一個 object,不致混淆,則省冠詞 如 symbolTable 而非 aSymbolTable Method 以動詞命名,如: buy (Desks myDesk)

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

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

46 演算法設計 例子 /* * showNames 顯示 houseList 各人名 * houseList 例 小華 阿偉 * Time estimate: O(n) */ private void showNames (HouseList houseList) loop 顯示 houseList 各元素所含的人名 end loop 46

47 9.補上程式碼 (Coding) 將虛擬碼改成註解 (加/* 及 */) 虛擬碼逐行補上對應之程式碼 儘量使虛擬碼易於閱讀
(常見舊程式難讀難維修,只好重寫)

48 補上程式碼 例子 注意:要凸顯虛擬碼 隱藏程式碼 以利閱讀
補上程式碼 例子 /* * showNames 顯示 houseList 各人名 * houseList 例 小華 阿偉 * Time estimate: O(n) */ private void showNames (HouseList houseList) /*loop 顯示 houseList 各元素所含的人名 end loop*/ for(i=0, i<=length(houseList-1), i++) println (houseList(i).name); 注意:要凸顯虛擬碼 隱藏程式碼 以利閱讀

49 10.單元測試 (Unit testing)及 驗收測試 (Acceptance testing)
單元程式(unit,即public method) 完成後, 用Junit 自動執行 test code 測試該單元 (unit) 這叫單元測試 單元測試要依呼叫順序反向(由下而上)來做 這叫 持續整合 (continuous integration) 某功能的單元都整合進系統後 駐點客戶依驗 收測試案例 逐一手動測試 這叫 驗收測試

50 單元測試 例子

51 Grade System Project (see next file)


Download ppt "軟體產業升級的利器 - 敏捷方法 中央大學資工系 陳振炎."

Similar presentations


Ads by Google