l

2011年2月27日 星期日

Designing for Error (2)

Feb. 27 21:32~22:58

昨天談到 The Psychology of Everyday Things (p. 131)提到的四點 Designing for Error 作法:

  • Understand the causes of error and design to minimize those causes.
了解錯誤發生的根本原因,在設計時盡可能避免這些錯誤發生。換句話說,這是 error prevention。一個最簡單的例子,如下圖所示,用行事曆的 UI 讓使用者選擇一個日期,這樣可以避免使用者打出 2011/02/29 這種不存在的日期。這個方法方法聽起來好像很簡單,如果有點年紀的鄉民們回想一下,在 Web 才剛剛流行的那個年代,透過網頁輸入『日期』的資料,大多還是只提供一個 text box 讓使用者自行輸入類似『2011/02/29』的期,或是三 text box 讓使用者自行輸入年,月,日。這種作法持續了一段時間,後來才有用 javascript 做的行事曆元件可用。所以,雖然『Understand the causes of error and design to minimize those causes』可以算是常識,但是在設計使用者介面時常常因為種種原因很容易被忽略。




  • Make it possible to reverse actions- to "undo" then - or make it harder to do what cannot be reversed
既然犯錯是難免的,如果有『月光寶盒』或是『時光機』可以回到過去『修正』自己所犯的錯誤,修正之後錯誤就不存在啦。換句話說,這是 error recovery。最常見的例子就是文書編輯軟體都有提供的無限次數 undo 功能,因為有了這個功能,使用者可以『無罣礙的(放心的)』編輯文件,反正萬一改錯了,只要 undo 就可以回到上一個狀態了。如果人生也能有 control+z 該多好

如果有些操作和人生一樣是無法 undo 那該怎麼辦?例如,鄉民們使用網路 ATM『轉帳』,網路 ATM 軟體人總不可能提供 undo 功能,讓鄉民們們在『不小時把錢轉給詐騙集團時』可按下 undo 按鈕吧。雖然這個功能聽起來很不錯,不過『轉帳』是不可逆也不可以 undo 的,而且不小心轉錯會『很傷』,因此,當使用者執行這類的功能時,軟體都會『再三提醒』,這也是這個作法第二部份所說的 make it harder to do what cannot be reversed




  • Make it easier to discover the errors that do occur, and make them easier to correct.
如果錯誤無法從根本上(在設計的時候)避免,那麼至少要能夠想方法讓『偵測錯誤』與『修復錯誤』變的簡單一點。舉個車子的例子,車子製造商無法用設計的方法『避免』使用者『忘記加油 (對車子而言這沒油了是一種錯誤)』,所以,他們設計了『油量指示表』,而且主動在『油量只剩下 10% 的時候亮紅燈或是發出 BBB 警告聲』( discover the errors),如果車子有 GPS 此時能夠自動結合 GPS 告訴車主最近的加油站在哪裡那就更棒了(make them easier to correct)。

再舉個軟體的例子,假設鄉民們正使用 Eclipse 用 Java 在寫程式。大家都知道,『寫程式是一件超級容易犯錯的工作』,Eclipse 的設計者如何幫助使用者(就是你)來 discover the errors 而且 make them easier to correct?人家想出了 quick fix 這個超讚的功能。以下圖的程式範例為例,Eclipse 偵測到一個語法錯誤(main method 遇到一個 checked exception 但是沒有 catch 或是 declare 這個 checked exception),在錯誤發生的那一行的左邊顯示了一個小X icon 稱之為 marker(以上是 easier to discover)。接下來是 easier to correct 的作法,當使用者按下這個小X icon 之後,Eclipse 顯示建議修改方案(resolution),使用者點選合適的修改方案 Eclipse 便自動幫忙修復這個錯誤。

當年 Teddy 曾經研究過 Eclipse 的 quick fix 機制,大體上就是:
  • 利用 visitor 去拜訪 Eclipse JDT (Java Development Tools)所建立的 AST (Abstract Syntax Tree)。Error detection 的邏輯就是寫在 visitor 裡面,plug-in 的開發者可以自行擴充新的 visitor 以便加入自己的錯誤檢查邏輯。
  • 當發現錯誤時,產生一個 麵包屑 marker 用以標示錯誤發生的『位置』(程式行號)。
  • 針對不同種類的 marker,plug-in 開發者提供自定的 resolution(解決方案)以協助使用者排除錯誤。由於 marker 是 plug-in 開發者依據『自訂檢查錯誤邏輯』所產生的一個『錯誤標記』,因此如果此錯誤『存在可能的解決方案』的話,plug-in 開發者自然可以事先提供 resolution 來協助使用者排除問題。當然,有時後這些 resolution 並不一定合用,需要使用者自己動手修改。
說真的,對於使用者而言,如果一個軟體系統有提供這種 quick fix 的貼心功能,真的是很方便。不過,要設計出這樣的功能是需要多耗費一點精神滴,對於各位加班加到暴肝的鄉民們而言,沒事應該不太想嘗試吧(Teddy 內心獨白:要向上提昇啊...)。


 
  • Change the attitude toward errors. Think of an object's user as attempting to do a task, getting there by imperfect approximations. Don't think of the users as making errors; think of the actions as approximations of what is desired.
最後這一點用書上的一段話來解釋並做本篇結尾 (p. 131):

When someone makes an error, there usually is good reason for it. If it was a mistake, the information available was probably incomplete or misleading. The decision was probably sensible at the time. If it was a slip, it was probably due to poor design or distraction. Errors are usually understandable and logical, once you think through their causes. Don't punish the person for making errors. Don't take offense. But most of all, don't ignore it. Try to design the system to allow for errors. Realize that normal behavior isn't always accurate. Design so that errors are easy to discover and corrections are possible.


以上四點以及上面這一段文字念個幾十次對於 designing for error 就會慢慢有 fu 了...


***

友藏內心獨白:好久沒翻這本書了,都快忘了這本書寫得有多好。

2011年2月26日 星期六

HCI 分類開張: Designing for Error (1)

Feb. 26 22:24~23:36

雖然不是 HCI 專家,但前兩篇(窮人 HCI 設計入門歪批 GOMS (1) ) Teddy 剛好談到這個主題,剛剛在『擠料』的時候,就想那乾脆把 Teddy 所知有限的 HCI 『小扁鑽』介紹給鄉民們好了,順便幫 Teddy 的部落格建一個 HCI 分類,把前兩篇文章從『軟工』移到『HCI』這個分類。

***

今天談談『使用者犯錯』這個問題(大哥內心獨白:我犯了全天下男人都會犯的錯誤),1-2 年前在 Discovery 上看到一個節目,討論英國某航空公司發生空難的案例。內容大概是該航空公司的某架飛機駕駛艙前方(或側面,有點忘了)的『玻璃』在飛機飛行中突然整片飛出去,導致飛機在高空中失壓。事後調查結果發現,該飛機在前天晚上才剛剛執行過一次例行的保養。為了避免『金屬疲乏』,技師才全部更換過用來鎖住玻璃的『螺絲』。最後的調查結果發現,是這些『螺絲』出了問題,因為它們的『size』不合... 小了一號(可能只差了 0.01 公分之類的)。

為甚麼『螺絲』會小一號?是買到『山寨版螺絲』嗎,還是用到『瑕疵品』,亦或是原廠裝貨的時候搞錯了尺寸?。都不是,原因是因為技師沒有依照『標準流程』拿取『螺絲』。『標準流程』規定要跟換螺絲時,要先去翻閱技術資料,確認飛機型號與其所使用螺絲的產品編號,然後在到領料處依據個產品編號來找出所要更換的螺絲。

如果這件事情發生在寶島台灣,鄉民們認為應該如何『處置』這位技師?
  • 人肉搜索,把他的祖宗八代的資料全部公佈在網路上。
  • 偷懶不按標準流程做事,危害飛安,抓起來槍斃...XD。
  • 找一群名嘴在政論節目中連續痛罵他三天,並開放『當事人澄清專線』讓他 call in 為自己辯解,之後在繼續狠批他的辯解。
還好這個事件是發生在英國,這位技師安然保存住性命。言歸正傳,為什麼技師不依據『標準流程』辦事,經過後續的調查發現:
  • 該技師已經有多次換過同型飛機的『螺絲』的經驗,因此他自認為不需要在逐一確認詳細的飛機型號與螺絲編號。
  • 該技師平常的工作量相當大,而且當天已經工作超時了(hT嘻,看到沒,工作超時是很危險滴)。在更換那架飛機螺絲的時候(當天最後一項工作),已經是深夜了,他想儘快完成後回家。
  • 因此,技師就把舊的螺絲拆下,拿到庫房去,用『肉眼』比對找出大小一樣的螺絲。沒想到這些新的螺絲肉眼看起來雖然和舊的一樣,但是實際上卻小了一點點。
  • 原本這一點點的差異並不會造成問題,巧就巧在飛機駕駛艙前方鎖住玻璃的那塊金屬已經有一個肉眼看不到的細小裂縫,在高空因為壓力,溫度等問題,最後造成整片玻璃脫落。

最後,航空公司並沒有特別懲罰該名技師,反而是檢討公司原本維修飛機的流程,來避免問題再次發生。

***

路人甲:這和 hT嘻 HCI 有何關係?

想一下,身為 developers,當有人向你回報說:『客戶操作我們的軟體,出現了 xxx 錯誤...』,你的典型反應可能是:『客戶不會用啦,都沒在看使用手冊的』,『這個地方我上次就告訴他要注意了啊,怎麼又犯錯了』。這些當然是很方便的回答,不用改任何軟體,反正就是客戶白爛就對了,叫他們回家深切反省並好好 讀書 讀手冊。也許有些情況下的確是如此,但如果總是以這樣的心態來思考客戶的問題那麼軟體就不可能『進步』(Teddy  內心獨白:使用手冊有寫這句話最近 Teddy 也常常掛在嘴邊...XD)。

軟體(或任何設計)應該要 Designing for Error,具體的作法在 The Psychology of Everyday Things (p. 131)這本書有提到。
  • Understand the causes of error and design to minimize those causes.
  • Make it possible to reverse actions- to "undo" then - or make it harder to do what cannot be reversed.
  • Make it easier to discover the errors that do occur, and make them easier to correct.
  • Change the attitude toward errors. Think of an object's user as attempting to do a task, getting there by imperfect approximations. Don't think of the users as making errors; think of the actions as approximations of what is desired.
明天要早起,有人在催 Teddy 準備就寢了,就先寫到這裡,明日繼續。重點是,心態轉變,『問題(錯誤)』也可能變成改善的好朋友。

***


友藏內心獨白:不思考問題發生的原因並從根本加以改善,直接把犯錯的人弊了還是無法根絕問題。總不能把 2千300萬人都弊了吧...XD

2011年2月24日 星期四

歪批 GOMS (1)

Feb. 24 22:25~23:46

昨天在『窮人 HCI 設計入門 』提到了使用 patterns 來設計與分析使用者介面的方法,剛剛在『擠料』的時候,突然想到了好幾年前曾經看過某篇介紹用 GOMS (Goals, Operators, Methods, and Selection rules) 來分析使用者介面設計好壞的 paper。由於年代過於久遠那篇 paper 到底跑去哪裡 Teddy 一時也找不到,只好匆匆到 Wikipedia 上面惡補一下。

先說明一下這四個名詞:
  • Goals: 使用者想要達成的目標,例如,一個文書處理器(word 或是小作家)的使用者,想要『列印文件』。『列印文件』這件事就是使用者的 goal。
  • Operators: 使用者為了達成某項 goal 所需要執行的(單一最小) action (動作),以『列印文件』而言,使用者所需要的 operator 可能包含了:
    • move mouse
    • click mouse left button
    • release mouse left button
  • Methods: 為了達到 goal 所執行的一連串 operators 就稱為一個 method。一個系統同時間可能會提供好幾種不同的 methods  來達成同一個 goal。以列印文件為例,
    • Method 1: 用滑鼠透過 tool bar 來列印文件
      • 移動滑鼠到 tool bar 上面 Print 這個 icon 上
      • 按下滑鼠左鍵
      • 放開滑鼠左鍵
    •  Method 2: 用滑鼠透過 menu 來列印文件
      • 移動滑鼠到 file menu
      • 按下滑鼠左鍵
      • 移動滑鼠到 print item
      • 按下滑鼠左鍵
      • 放開滑鼠左鍵
    •  Method 3: 用鍵盤透過 menu 來列印文件
      • 按下 alt-f
      • 放開 alt-f
      • 按下 p
  • Selection rules: 如果同時存在一種以上的 method 都可以達成相同的 goal,則我們透過 selection rule 來描述在何種情況下應該選用哪種 method 會比較合適。
由於 GOMS 所描述的最小單位是 operator (按下鍵盤上的一個 key,移動一次滑鼠都算一個 operator),因此我們只要很簡單的去『加總』某個 method 所包含的 operators 就可以比較出用該 method 來達成某個 goal 是否合適,或是還有沒有改善的空間。

***
 再舉個例子,看一下 Teddy 家裡 Firefox 所顯示的『印列對話盒』:


從這個畫面可以看出來 Teddy 有三個印表機設定(實際上有兩台印表機),由於『印列對話盒』會記住 Teddy 的預設印表機,因此當 Teddy 要透過這個畫面列印文件的時候,只需要:

method 1:
  • 移動滑鼠到『列印』按鈕上
  • 按下滑鼠左鍵
  • 放開滑鼠左鍵
或是 method 2:
  • 按下 alt + p
  • 放開 alt + p
但是,如果 『印列對話盒』沒有記住 Teddy 的預設印表機,那結果就變成:

method 1:
  • 移動滑鼠到預設印表機上
  • 按下滑鼠左鍵
  • 放開滑鼠左鍵
  • 移動滑鼠到『列印』按鈕上
  • 按下滑鼠左鍵
  • 放開滑鼠左鍵
硬是多了三個 operators

或是 method 2:
  • 按下 tab 讓 focus 移到選擇印表機的這個 UI 元件
  • 放開 tab
  • 按下『方向鍵』(向上或向下) 移到所要選擇的印表機上
  • 放開『方向鍵』
  • 按下 alt + p
  • 放開 alt + p
活生生又是多了四個 operators

***

路人甲:一定要玩到這麼『龜』嗎!連一次滑鼠移動或是按一個按鍵都要計較。

沒錯,就是要『斤斤計較』。通常 developers 可能只有在開發軟體的時候會使用自己所開發的軟體,在那之後就很少會用到。但是,你的客戶很可能是每天都要用好幾個小時以上。就算是使用者為了達到某個 goal (例如,新增一筆客戶資料)只增加三次不必要的 operators(例如,移動滑鼠,按下滑鼠右鍵,放開滑鼠右鍵),萬一這個使用者一天要新增 100 筆客戶資料,那他就活該倒楣要多操作 3 * 100 = 300 operators。

這還只是為了完成一個 goal 而已,一整天下來如果要完成 N 個 goals,這個倒楣的使用者不腰酸背痛才有有鬼。長久下來,不到 35 歲就需要去看復健科門診了。

很多使用者介面,雖然好像只是『沒有把 cursor 移到預設的位置』,『沒有設定正確的 tab order』,『沒有 focus 在正確的 UI 元件上』這種小事,對於經常使用該軟體的使用者而言卻是大事。Teddy 還記得第一次跟 Kay 借用 iPhone 來玩,那種『增一分太肥,少一分太廋(恰到好處)』的感覺,不禁發出『為什麼人家的使用者介面可以設計的那麼好用』的感嘆。相較起使用 學弟 某人設計的軟體,卻發出了『為什麼用完之後 Teddy 的手肘那麼的酸痛』的感嘆... XD。

***

程式寫得再美,使用者不會去幫你做 code review,看不到你的『內在美』,所以還是賣不出去。介面設計的好,使用者用起來很爽,就有賣點了。也許這樣講不盡公平,你會說介面設計的好但是玩兩分鐘就當機了啊。但是,至少你的客戶願意花兩分鐘來玩。介面設計的爛,客戶可能只願意花『一眼』,連動手都省了。

***

友藏內心獨白:Programmers 除了寫程式以外還是要懂一些 HCI 設計方法,『小扁鑽』還是有需要滴,捅人自捅兩相宜。

2011年2月23日 星期三

窮人 HCI 設計入門

Feb. 23 21:01~22:35

如果鄉民們和 Teddy 一樣都是 programmers 的話,在開發軟體的時候一定會遇到一個問題:『使用者介面要如何設計?』平平都是做手機的,人家 Apple 的 iPhone 使用者介面就設計的那麼好,而我們的卻那麼...鳥...(這一句要用唱的:人家的介面是真正的介面,我們的介面是人家不要的我們把它撿起來...)。你可能會不服氣的說,人家 Apple 或其他國際級的大公司,都有專門研究『人機介面』或是『使用者介面』的人,設計的好是應該的。好吧,有鑑於台灣都是『中小企業』居多的這個特性,想要和這些『財閥』相比是很難滴,但是軟體還是要寫啊,就算不是要賣錢的,只是給公司內部使用的系統,軟體介面不好用也是會常常被使用者念個不停甚至被恥笑。

Teddy 相信這個問題一定困擾著不少的 programmers,因為你可以把程式寫得很好,但是卻不一定知道要如何把『使用者介面設計的很好(容易)使用』。有些開發團隊雖然有所謂『設計介面』或是『做網頁的人』,這些人雖然可以把『畫面做出來』,但卻不一定具備設計容易使用介面的知識與能力。從軟體開發的角度來看,研究這個問題的領域叫做『人機互動』(Human-Computer Interaction, HCI) 或是『人機介面』(Human-Computer Interface, HCI)。由於台灣人常常抱持著『先研究不傷身體,再講求藥效 先讓軟體可以動起來,再研究好不好使用』的心態,因此在人力不足的情況下,軟體的介面設計的工作常常落到 developers 的身上。而 developers (不要看別人,就是你啦)在缺少對於 HCI 相關訓練的情況下,要設計出『有質感又超級貼心的介面』的機會大概比中統一發票特獎的機率還要低一點。

假設你是 team leader,由於上輩子燒好香,在你的團隊中擁有所謂『做網頁的人或是設計UI 的人』,你是否常常會覺的這些人的『網頁(UI)設計的不夠好』但是卻因為自己缺少 HCI 的知識而經常有『就算想開罵卻不知從何罵起』的遺憾(友藏內心獨白:讓恁爸來罵一定可以罵到『牽絲』)。來來來,有以上困擾的鄉民們,今天 Teddy 介紹這一帖藥,服用後只要『光呼吸就可以達到減肥的效果』,保證一週內最少可廋 5 公斤...XD

藥方就是 Jenifer Tidwell 的...知道這個作者的人會以為 Teddy 要介紹 Designing Interfaces 這本書,答錯。這本書太厚了,看不下去(而且要錢)。這邊有免費的 paper  可看:

COMMON GROUND: A Pattern Language for Human-Computer Interface Design

這篇 paper 顧名思義就是要介紹好幾個 HCI 的 patterns。可能是 Teddy 看  patterns 看習慣了,總覺的 Jenifer Tidwell  的這篇 paper 寫得比 Designing Interfaces 這本書要容易閱讀。 Jenifer Tidwell  在 paper 中將她所提出來的 HCI patterns 分了好幾的類別,每一個 pattern  的內容就請鄉民們自己花時間去看(Teddy 可以幫鄉民們們省錢但是卻沒辦法幫鄉民們省時間啊),在這邊看一個 Teddy 覺的很有用的分類和其所包含的 patterns 與每一個 pattern 的 solution:

How does the content or available actions unfold before the user?
  • Navigable Spaces:Create the illusion that the working surfaces are spaces, or places the user can "go" into and out of. 
  • Overview Beside Detail:Show the whole set of objects, or the whole undetailed data set, in one part of the display area, to act as an overview of the content.
  • Step-by-Step Instructions: Walk the user through the task one step at a time, giving very clear instructions at each step.
  • Small Groups of Related Things: Group the closely-related things together, nesting them in a hierarchy of groups if needed.
  • Series of Small Multiples  (unwritten): 歹勢,作者沒寫。
  • Hierarchical Set: Show the data in a tree-like structure. 
  • Tabular Set: Show the data in a table structure.
  • Chart or Graph: Show the data plotted against time or some other variable. Plot it together with other variables for further comparison
  • Optional Detail On Demand: Up front, show the user that which is most important and most likely to get used. Details and further options which won't be needed most of the time -- say 20% or less of expected uses -- can be hidden in a separate space or working surface (another dialog, another piece of paper, behind a blank panel). 
  • Disabled Irrelevant Things: Disable the things which have become irrelevant.
  • Pointer Shows Affordance: Change the affordance of the thing as the pointer moves over it.
  • Short Description: Show a short (one sentence or shorter) description of a thing, in close spatial and/or temporal proximity to the thing itself.

Step-by-Step Instructions 為例,這個 pattern 所要解決的問題是:

How can the artifact unfold the possible actions to the user in a way that does not overwhelm or confuse them, but instead guides them to a successful task completion?

也有人把這樣的 pattern 叫做  Wizard,講這個名字大家就瞭了。當各位在設計使用者介面,或是 review 別人設計的介面時,如果了解了這些常用的 HCI patterns,至少就有一種可以用來評估的標準。舉一個最簡單的例子,假設你的程式有一個『Print』的功能,可是使用者的電腦並沒有裝印表機。『照理講』一般正常的地球人在此情況下會把這個『Print』功能(例如畫面上的 Print button)給 disable。但是,恰巧你聘請的是遠從火星來的 programmer,沒有把『Print』功能給 disable。

路人甲:有人這麼白目的嗎?

Teddy:別懷疑...

相信鄉民們都是受過高等教育的地球人,當遇到這樣的火星人一定要用有教養的方式來教育他。

地球人:你是『丁丁』啊... 說溜了嘴...來來來,...近一點,先來個愛的抱抱,再讓我教你,這邊應該要套用 Disabled Irrelevant Things 這個 pattern 喔...

火星人:喔...嗯...那泥...原來還有這一招...偶了解啦...(偶是許x美,不是丁丁啦)

地球人:一定要幸福喔...XD

以上...差不多就是這個意思了。

***

不知道鄉民們有沒有注意到,這篇 paper 的標題叫做 COMMON GROUND,看到這裡應該就了解了吧。如果不知道讓 Teddy 說給你聽。在還沒有學習這些 HCI patterns 之前,地球人和火星人在溝通使用者介面上遇到困難。但是,雙方都學習了 HCI patterns 之後,就有一個『共通的基礎』可以相互討論了。

看到這邊一定會有鄉民們想說:『我聽 Teddy 你在哪邊放風吹(風箏)』... 實際上 UI 設計哪有那麼簡單... 是沒那麼簡單,HCI 還包含了很多議題,例如 task analysis 和 usability 以及設計精美的小 icon 。但是在練會絕世武功之前,好歹先買把『小扁鑽』隨身攜帶著,不然是很難在『艋舺 軟體界』立足滴。免錢的加減用一下。

***
友藏內心獨白:有便宜的牛內還不趕快搶。

還少一本書:The Unified Software Development Process

Feb. 22 22:41~ Feb. 23 00:16

昨天介紹了對於了解與實做 CMMI 有助益的 Managing the Software Process 這本書,今天就順便介紹一下 The Unified Software Development Process 這一本。本書的作者也是鼎鼎大名的三巨頭 Ivar Jacobson, Grady Booch, James Rumbaugh。如果說昨天介紹的 Watts S. Humphrey 博士是 CMMI 之父,那麼今天介紹這三位 (Jacobson, Booch, Rumbaugh) 可以說是 UML 之父了。

這邊先澄清一個觀念,就好像常常有人會說:『我們團隊使用 CMMI 流程來開發軟體』這種錯誤觀念(CMMI 並不是一種開發流程,原因請參考昨天內容),也常常會聽到有人說『我們使用 UML 來分析軟體專案』或是『我們使用 UML 來開發軟體』這樣的錯誤說法。哪裡錯了?

  • UML 的全名是 Unified Modeling Language,這邊偷用一下 wikipedia 的解釋 『UML includes a set of graphic notation techniques to create visual models of software-intensive systems.』所以常常有人說 UML 『只是』一種『畫圖(講好聽一點就叫做 visual modeling)』的表示法而已。了解這一些標準的『畫圖表示法』,例如 Class diagram, Sequence diagram, Activity diagram, Use case diagram 等等,並不能說你就知道要如何『分析』軟體。就好比知道各種幾何圖形並不表示你知道要如何畫出一幅好的圖畫一樣。這是兩件事情。
  • 你可以用 UML 來表達軟體設計,但是你不能用 UML 來『開發軟體』。你可能會不服氣的說,可以啊,書上有說,UML 圖畫好之後按下『Code Generation』就把程式自動產生好了,還可以選要產生 Java, C# 或是 VB.NET 各種不同的語言喔,連一行程式都不用。也許有一天大家真的可以用這種方式來『開發軟體』,但不是今天。
明明是要介紹 Unified Software Development Process (簡稱 Unified Process, UP) 為什麼 Teddy 又扯到 UML... 因為 UP 和 UML 的作者都是同一批人,而且在看 UP 書籍或相關資料的時候,又經常看到一堆有的沒的 UML diagrams ,所以鄉民們很容易就會 UP, UML 傻傻分不清楚

再幫鄉民們問一個問題,那沒事幹麼學 UP,不是用 SCRUM 或 XP 這種 agile methods 就好了?答案也很簡單:
  • 現實世界中,專案的大小,型態各異,多了解幾種軟體開發流程可以讓自己面對到不同的專案時,有多一點的選擇。就好像一個 programmers 不可能只會一種 programming language 一樣。就算你覺的 Java 是全世界最棒的語言,如果你真的傻傻的一輩子就只會 Java,那是很危險滴。
  • 和別人(『』)吵架的時候,多知道一點東西比較不會被唬的一愣一愣的。有人說『知識就是力量』,Teddy 說,『知識就是吵架本(吵架的本錢)』。
***

Teddy 的部落格都是『當天現撈的』,常常一不小心寫太晚搞得 Teddy 晚上失眠。接下來以大易輸入法的方式快速介紹一下本書重點。

UP 的三大支柱:
  • Use-Case Driven:這一點其實很有趣,如果了解 Scrum 的人把 Use-Case Driven 換成 Story Driven 這樣就可以了解這一點的含意。在 Scrum 中,軟體開發流程是在每一個 sprint 中挑選若干個 story 來開發,最後在第  N 個 sprint 的時候把軟體做完。所以我們也可以說 Scrum 是 story driven (story 『驅動』著 Scrum 流程的每一項活動)。在 UP 中,這樣的精神是很類似的,只是 UP 用來紀錄需求的單位是一個 Use Case。
  • Architecture-Centric:這一條解釋起來比較難一點,大體的精神是在軟體開發的『較早階段』,利用先『實做』最重要 5%~10% Use Cases 的機會建構起 software architecture 的『雛型』。日後隨著越來越多的 Use Cases 的內容被釐清與實做,這個 architecture 逐漸『轉大人 成熟』。
  • Iterative and Incremental:這一點就比較沒什麼好解釋,UP 和現代主流的軟體開發流程一樣,都是支援 IID 的流程 (Iterative and Incremental Development Process)。
其實這本書的重點 Teddy 已經講完了,了解這三點之後,是很有幫助的。有時候 Teddy 甚至懷疑自己在採行 Scrum 的時候都有被 UP 『附身』而渾然不知的情況。鄉民們仔細想一下,想不起來的 Teddy 再幫各位複習一下,其實 Scrum 這個框架可以很簡單的用下面幾點表示:
  • Role:Product Owner, Scrum Master, Team (Developer)
  • Activity:Sprint Planning Meeting, Daily Scrum, Sprint Review Meeting, Retrospective Meeting
  • Artifact:Story, Sprint Backlog, Sprint Backlog, Task Board, Release Plan
那... 對於要如何『開發軟體(分析,設計,實做,測試,佈署...etc)』Scrum 是沒有規範的。往好的方面來講這樣是『很有彈性』,從壞的方面來講這樣是『太有彈性以至於不知道要怎麼進行』(怎麼評價端看你是汎藍還是汎綠的...XD。所以,無論是採用哪種流程,基本的『分析與設計能力』還是要有的。不管你使用傳統的『結構化分析與設計』或是目前主流的『物件導向分析與設計』,在不同的流程中都是必備的技能。關於這些分析與設計的技巧,在 Scrum 是不管你的(Scrum 內心獨白:給你彈性啊),在 UP 中就提的比較多。所以,這本書介紹完 Use-Case Driven, Architecture-Centric,Iterative and Incremental 這三個觀念之後,緊接著就介紹 UP 所謂的『core workflows』:
  • Requirements Capture
  • Capturing the Requirements as Use Cases
  • Analysis
  • Design
  • Implementation
  • Test
鄉民可以把這些介紹 『core workflows』的章節當作學習某種『分析與設計方法』。說真的雖然當年 Teddy 為了考資格考不得已將這些『core workflows』很認真的讀了好幾遍,但是到現在早就忘的差不多了。耶,Teddy 還是活的好好地,所以應該.... 沒看也沒關係。Teddy 覺的這本書介紹的 『core workflows』 過於『正規』了一點,光是為了搞懂這些『表示方法』所花的時間與在實做上所帶來的真正好處相比,C/P 值似乎太低了一點。如果要學分析設計方法,還不如直接去看 Crain Larman 的 Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development 這本書就好了(書名還真是長)。

像是書中介紹 Use Case Realization 這個概念,Teddy 曾經聽說有公司在面試工程師的時候還拿來當考題...說真的,現在 Teddy 也答不上來。不過再強調一次,Use-Case Driven, Architecture-Centric,Iterative and Incremental 這三句話一定要熟記,非常有用的觀念。Teddy 在採用 Scrum 開發專案的時候,其實內心裡一直默背這三句『口訣』,尤其是 Architecture-Centric 的精神如果可以掌握,對於避免『不要因為採用逐步成長的開發流程就讓軟體長壞掉』這件事佔有重要的地位(當然 refactoring 與自動化測試也是必須的)。

***

友藏內心獨白:不要以為 Teddy 只會  Scrum 喔... 啊,還是寫太晚了。

2011年2月21日 星期一

還少一本書:Managing the Software Process

Feb. 21 21:28~ 23:41

前一陣子 Teddy 看到一個消息,Watts S. Humphrey 這位軟工界的大師過世了(4 July 1927 - 28 October 2010),這算是軟工界一個很大的損失 。Humphrey 博士寫了很多軟體工程方面的書籍與論文,對軟工領域可謂貢獻良多。大體上 Humphrey 博士的精神是『一個流程如果無法測量,就無法改善』,因此在他的書中可以看到很多制式的表格,提供軟體開發者一個『測量』的基準。這種精神反應到了極致,就是在軟工界鼎鼎有名的 CMM 以及後來進化版的 CMMI,因此有人稱呼 Humphrey 博士為 CMMI 之父。

今天要推薦的這本書就是 Humphrey 博士在 22 年前所寫得 Managing the Software Process 這本書。

路人甲:Teddy 你不是 agile methods 這一國的嗎,怎麼可以『為匪宣傳』?


路人乙:1989 年出版的『舊書』現在還在推薦?

***

還沒開始介紹就有鄉民們看的不爽了,請容 Teddy 娓娓道來。首先,Teddy 並沒有『討厭』或 『反對』CMMI。而且 CMMI 並不是一種『流程』,而是一種『評估流程成熟度』的框架(方法),軟體團隊可以選用任何的流程來達到 CMMI 所要求的評估標準。你可以用 Waterfall,用 RUP ,用 agile methods, 或用吸星大法,只要符合 CMMI 對於每一個流程成熟度等級的要求便可(當然如果要獲得證書是需要花一筆錢滴)。

講的再白話一點,CMMI 就是一種『評鑑標準』,就好像唸國中的時候學校有『整潔競賽』一樣,整潔競賽的評分標準有『地上有沒有垃圾』,『抽屜有沒有髒東西』,『桌椅有沒有對齊』,『黑版有沒有擦乾淨』,『垃圾有沒有倒』,『門窗電燈有沒有關好』,『打掃用具有沒有歸位』等等囉哩八唆的一堆規定。打分數的老師就用這些『評鑑標準』來評量你們班級的『整潔成熟度等級』。至於要如何達到『高整潔成熟度』,則是不會被規範在『評鑑標準』中。有的班級可能會用『排值日生』的方式,有的人會要求『全班留下來打掃』,有些『富二代』的班級可以把打掃工作『外包』,有的班級可能會花錢買 『iRobot』 外加『好神拖』以提昇打掃效率(一個以 xxx 工具支援的自動化打掃流程...XD)。總之不管是黑貓白貓,只要能通過『評鑑標準』的就是好貓。是不是這個意思?就是這個意思。

講了這麼多好像都不是重點... 總之:

(1) 介紹 Managing the Software Process 或是 CMMI 不算為匪宣傳。
(2) 此書雖然已經出版 22 年了,但是如果你是那種『測量的擁護者』,那這本書還是十分值得一看。此外,本書還是有很多軟體工程觀念,作法與名詞介紹,歷久彌新。
(3) 就算你是那種很不爽 CMMI 的人,還是要看。如果不『深入敵營』,如何打探消息並將敵人殲滅。


***

終於要講到書中內容,第一章開宗明義介紹 A Software Maturity Framework

The objectives of software process management are to produce products according to plan while simultaneously improving the organization's capability to produce better products. The basic principles are those of statistical process control....

The basic principle behind statistical control is measurement.

第一章提到了五個 process maturity levels:
  • Initial
  • Repeatable
  • Defined
  • Managed
  • Optimizing
***

第二章介紹 The Principles of Software Process Change

  • Major changes to the software process must start at the top. (就是說老闆要出來鎮壓反對勢力,至少不可以自己帶頭反對...XD)
  • Ultimately, everyone must be involved. (就是說最終要把公司上上下下每個人都搞得很累...XD)
  • Effective change requires a goal and knowledge of the current process. (減肥前要先拍照『證明』自己胖的跟條豬一樣,這樣減肥成功後才可以拿來跟前男友炫耀...XD)
  • Change is continuous. (改善是沒完沒了滴,就是說顧問的錢要一直付下去不可以省...XD)
  • Software process changes will not be retained without conscious effort and periodic reinforcement. (這一句也很重要,想一下,連 Scrum  裡面都有若干角色/機制可以呼應這一點。)
  • Software process improvement requires investment. (Teddy 內心獨白:這一條的意思應該不是叫大家每次都花個 100 萬新台幣去換個 CMMI Level X 證書吧... XD)
***


有看電視的人都知道,醜女(男)在進行大改造之前,都要被現場來賓狠狠的批評一下。同理可套用在軟體流程改善上。第三章介紹 Software Process Assessment 的幾點原則。
  • The need for a process model as a basis for the assessment.
  • The requirement for confidentiality.
  • Senior management involvement.
  • An attitude of respect for the views of the people in the organization being assessed.
  • An action orientation.
***


第四章談 The Initial Process,也就是 Level 1。一言以蔽之,Level 1 就是『亂七八糟』。接下來 5-8 章介紹 The Repeatable Process;9-14 章是 The Defined Process;15-16 章是 The Managed Process;17-20 章是 The Optimizing Process。在此列舉幾個大家比較熟悉的內容:
  • 第六章 The Project Plan
  • 第七章 Software Configuration Management (Part 1)
  • 第八章 Software Quality Assurance
  • 第十章 Software Inspections
  • 第十一章 Software Testing
  • 第十二 Software Configuration Management (Part 2)
  • 第十七 Defect Prevention
  • 第十八 Automating the Software Process

***

總之,這本書用『工程』的方法告訴鄉民們『軟體應該要這樣開發滴』... 不管看完之後是否買帳,多了解一種看法也是不錯的。另外,這本書不會只告訴你要達到 Level x 『應該』做這個,做那個,而且會實際告訴你『實做方法』。如果想導入 CMMI 的人看這本 CMMI: Guidelines for Process Integration and Product Improvement  書看的一頭霧水的時候,不仿先看看 Managing the Software Process。

***

友藏內心獨白:Humphrey 博士 2010 年 10 月逝世,而他的最後一本書 Reflections on Management  出版於 April 8, 2010。這豈不是說他老人家到生命的終點都還在寫書... 真是太令人敬佩了。

2011年2月20日 星期日

秀才遇到兵

Feb. 19 22:20~ Feb. 20 00:08

Teddy 發現這幾年陸陸續續所寫的近二百篇文章中,點閱率比較高的像是『600 多個 bugs 要怎麼修? 』,『老闆,軟體不是這樣開發滴』以及『改行寫網路小說算了』,都有一個共通點,就是隱含著一種『秀才遇到兵,有理說不清』的無奈。相信這種感覺也是許多鄉民們內心小小的吶吼,所以才比較容易引起迴響。至於那些太技術性的文章,就當作 Teddy 自己寫爽的,充充業績之用。


秀才,當然就是咱們這些頑劣不冥的 攻城屍 工程師們,至於兵的『可能性』就很多了:
  • 聖上:豈只是『兵』,還且還是『天.....天都準時上班的...大兵』,一句話就可以讓你消失在地球表面,殺傷力 100%。
  • 九品芝麻官:天高皇帝遠,聖上殺傷力雖大,但總不會天天都給你一道聖旨,但九品芝麻官(直屬主管)就不同了。運氣好遇到那種每天盯死你的,讓你一想到要上班就憂鬱起來。遇到勤政愛民的九品芝麻官也就算了,但絕大部分都是那種善於揣摩上意,逢迎拍馬,找代罪羔羊的貨色。九品芝麻官在『大清帝國』龐大的官僚體系中多官位雖小,但絕不可小覷。就好比一把只要三塊錢新台幣的『超級小刀』,每天只要被刺一刀縱使你有再多的血也不夠流啊。
  • PM :俗話說『好的 PM 帶你上天堂,不好的 PM 讓你虛工做不完』。有些 PM 好像上班的時候忘了把大腦帶出們,遇到問題只會『轉寄 email』。把客戶的 email 轉給工程師,或是把工程師對於需求的問題直接轉給客戶,似乎已經變成這種 PM 的反射動作(還記得嗎,反射動作是不需要經過大腦思考滴)。如果 email 『轉得好』也就算了,有時候把該給 testers 的 email 要求 programmers 去做,掀起一場無謂的『內鬥』,有這種 PM 國家 公司還需要敵人嗎?殺傷力以『三國人物』來看的話,也算是『張飛』這種等級了。
  • 大牌業務:仗著『全公司都是靠我在養』的氣勢,大牌業務要你們這些手無縛雞之力的『秀才』作詩,你就得在『七步之內』吟出一首五言絕句(Teddy 內心獨白:我又不是曹植),叫你畫畫你就得在三分鐘內畫出一幅『春樹秋霜圖』(Teddy 內心獨白:先把秋香拿出來人家才要畫啦...XD)。要小心這些大牌業務都有『密奏之權』,可直達天聽,要是你好膽拒絕他們的要求,下場可是會『暗箭』穿心。
  • 同事:雖然『理論上』秀才的同事應該也是秀才啊,可是有時候你的秀才同事可能會『投筆從戎』,一不小心也變成小兵了。
  • 顧客:出錢的是大爺,遇到這種『兵』只能當作『清冰』... 加減吃... 就算現在外面溫度只有 攝氏10 度加上細雨綿綿你還是得把這碗『御賜清冰』給它『吞下去』。
但是,從『兵』的角度來看,這些『秀才』才是『不知天高地厚』的人。『兵』叫你作什你就做什麼,那來的那麼多意見。這個也不做,那個也不行,那你俸祿還要不要領?(兵內心獨白:國庫只剩下四百萬兩的壓庫銀了...)


 ***

有一次 Teddy 在和指導教授在討論某個研究題目的時候,他曾經說過類似的話(細節 Teddy 已經忘了,大意如下):

美國(西方)雖然很強調科學,但是老美內心其實有一種反科學(瞧不起科學)的意識。你看很多老美的電影裡面,壞人在一個高科技的實驗室內正要做出危害全人類的勾當,此時類似『藍波』這種『頭好壯壯』的肌肉猛男在最後一刻及時趕到打倒了壞人。壞人警告肌肉猛男,千萬不要隨便亂碰任何按鈕,否則就會立刻爆炸。眼看剩下倒數 10 秒鐘壞人所設定的炸彈就要啟動了,『頭好壯壯』的肌肉猛男完全不鳥壞人的警告,二話不說,拿起手上的衝鋒槍朝這些『高科技設備』一陣掃射..... 沒事,狀況解除,肌肉猛男再次拯救世界。

 ***

如果把『肌肉猛男』換成『秀才』那就完蛋了,剩下 10 秒哪可能讓『秀才 』在那邊慢慢研究解除炸彈的密碼。有時候 Teddy 也會懷疑,學那麼多有的沒的真的有用嗎?也許真實世界需要的是『肌肉猛男』而不是『秀才』。

友藏內心獨白:這一篇在寫什麼連 Teddy 自己都看不懂...XD

2011年2月17日 星期四

第 N 度空間

Feb. 17 21:55~23:43

警告!本篇包含怪力亂神之言論,無法默寫出 Java 語言全部的保留字的鄉民們請勿觀看,不聽勸告者觀後若有任何不良影響後果自負。

Teddy 訂了好幾年的科學人(其實是 Kay 訂的,Teddy 只是看免錢的) ,很可惜沒有因此而變得比較科學一點。科學人不是所謂的『科普雜誌』嗎,意思就是『給 死老百姓 普通人看的科學雜誌』,為什麼每期 Teddy 平均大概只看得懂不到 30% 的內容?看來 Teddy 淪落到此 賣笑 搞笑也不是沒有原因滴。

記得有一期科學人在講『宇宙』和『時空』的概念,文中提到科學家為了解釋物理定律,因此提出了什麼五度,六度....N 度空間的概念,因為這些概念在平常我們所熟知的四度空間內不容易(或無法)被處理。在此 Teddy 幫鄉民複習一下,一般所謂的二度空間(平面空間,需要 x, y 來表示),三度空間(立體空間,需要 x, y, z 來表示)四度空間(就是加上時間這個因素)這些都比較容易理解,那到底其他的 五度,六度,七度,八度... N 度空間是怎麼一回事(Teddy 內心獨白:難道好神公仔與阿飄的世界也要各算一度空間?)物理很不強的 Teddy 就無法理解了,不過話說回來,這些物理學家腦袋裡面在想什麼相信不是咱們這些凡夫俗子可以理解的。

最近 Teddy 遇到一個 Java 語言的問題,解完這個問題之後,突然對『某些問題只有在 N 度空間才能夠被解』這件事情有所領悟。話說『某人』想要知道,在 runtime 當 Java 程式收到(catch)一個 exception 的時候,要如何得知該 exception 是從那一個 method 中所丟出來的。以下舉個例子:

public void caller () {
    
    Callee callee = new Callee();

    try {
        callee.test();
        callee.test(100);
        callee.test("this is a test");
      }
       catch(Exception e) {
        // e 是被哪一個 test method 所丟出?
      }
}

public class Callee {

    public void test() throws IOException {
            .....
           throw new IOException();
    }

    public void test(int param) throws IOException {
            .....
           throw new IOException();
    }

    public void test(String param) throws IOException {
            .....
           throw new IOException();
    }
}
***

懂 Java 的鄉民們麻煩動動腦,一起想一下這個問題要怎麼解。乍看之下這個問題很簡單,以下是 Teddy 的學弟利用 Java Reflection 機制所提供的解:

            StackTraceElement element = e.getStackTrace()[0];
            Class aClass = Class.forName(element.getClassName());
            Method method = aClass.getMethod(element.getMethodName());

Java StackTraceElement 物件雖然提供了該 exception 所發生的 method 名稱,以及行號,但是對於 overloaded methods 光有 method name  是不夠的(因為 method names 都一樣啊),還需要有『參數』才能夠判別到底是那一個 overloaded methods。以最前面那個例子而言,光是知道 method name 叫做 test 是不夠的,還要知道是沒有參數的那一個 test,或是接受一個 int 參數的 test,或是接受一個 String 參數的 test。很可惜 StackTraceElement 物件並沒有提供 method 參數這個資訊。

聰明的鄉民們可能會說,阿都可以知道該例外是在程式第幾行被丟出來的(可以從 StackTraceElement 物件的 getLineNumber() 得知),怎麼會沒辦法知道那一行是屬於哪一個 method?是啊,為什麼沒辦法?『某人』和 Teddy 就算把學弟打死,還是沒辦法。如果有 source code,當然可以知道 exception 是從哪一個 method 丟出來的,問題是,請複習一下需求:

在 runtime 當 Java 程式收到(catch)一個 exception 的時候,要如何得知該 exception 是從那一個 method 中所丟出來的。

請注意,是 runtime,正常情況是拿不到 source code 的,只有 bytecode。原本 Teddy 也以為是學弟偷懶不認真研究 Java Reflection 所以才找不到答案,後來 Teddy 自己下海找了 2 小時,發現好像還真的是無解。


***

講到這邊,一般正常人都會有個疑問:這和『第 N 度空間』有何關聯?是滴,Teddy 把 Java 語言提供的否些『功能』看作一種『空間』,這樣就扯上關係了。先從 Java  最基本的控制流程開始,例如 assignment,statement,loop,condition 這一些在傳統 procedure oriented languages (程序導向語言,例如 C)都有的功能,看成一種『空間』,有些問題在此空間就可以解決了,例如,用 Java 寫出 1 加到 100 的程式,根本不需使用其他『空間』(例如物件導向)來解這個問題。事實上,Teddy 看過很多『把 Java 當成 C 來用的程式』,也是跑得好好地。

問題是,當軟體系統大到一定的程度,人們發現光是用『程序導向空間』來解問題不足,因此有人就加入了『物件導向空間』來幫忙處理一些在『程序導向空間』不容易處理的問題。什麼問題?請自行複習一下 Class, Object, Interface, Inheritance, Polymorphism 這些機制。再過一陣子,又有一些前輩們發現,有些問題還是不容易解決,於是又產生了『Reflection  空間』。如果沒有 reflection,programmers 就不能用Class.forName 的方式在 runtime 的時候依據某個字串(某個 class 的 name)動態載入該個 class。當然 reflection 還有其他更多的用途,有興趣者請自行研究。

講到這邊,已經提到了 Java 三個空間了。還有沒有?當然有。Annotation 也可以算是另一度空間,有了 annotation ,programmers 就可以用達到某種程度的 『宣告式程式設計』。相信以上所提的 Java 四度空間一般的 Java programmers 都了解,很遺憾,在這四度空間中 Teddy 『一時』(要強調一下,是一時,說不定 Teddy 的問題可以在這四度空間中被解,只是 Teddy 還沒發現)沒能發現解法,還好 Teddy 有『通靈』的能力,當年在研究『如何在 Java 語言中實做 Design by Contract』這個題目的時候,花了好幾個月的時間在和 Java bytecode 搏鬥,因此知道這個問題在第五度空間『Java Bytecode』應該有解

請看一下 Teddy 用看 bytecode 軟體所開啟某個 Java class 的畫面。


在 bytecode 中,每一個 method 可以夾帶一種 LineNumberTable 的資料結構,在這個資料結構中會紀錄該 method 丟出 exception 的行號 (圖右方的 line_number 這個欄位所紀錄的值)。看到這邊答案就很清楚了,從 exception 物件可以得到 StackTraceElement 物件,然後再從 StackTraceElement 物件可以得到 exception 丟出點的行號。把這個行號拿來和 bytecode 裡面的 LineNumberTable 比對,如果數值一樣就找到丟出該 exception 的那一個 method  了。正所謂『江湖一點訣,說破不值錢』(怎麼覺的和變魔術那麼像?!),可以準備講完收工了。


鄉民甲:等一下,那要怎麼去讀 bytecode 裡面的資料?

Teddy:很簡單,網路上找一下就有答案了,有現成的 libraries 可以用。



***

解了這個問題之後,Teddy 才深深的感受到『有些問題在某些空間中比較容易被解』這件事。身為一個 Java programmers,如果對於上述的 Java 五個空間不了解,遇到問題時相對的可以使用的『工具』就比較少。至於在 Java 或是其他類似的語言到底有『幾度空間』其實 Teddy 也沒想過這個問題,不過肯定是『超過五度空間』。你問 Teddy 為什麼?啊因為隨便想都還可以想出好幾個啊...


***

友藏內心獨白:這種東西也敢寫出來...XD

2011年2月13日 星期日

改行寫網路小說算了

Feb. 13 21:39~22:59


有一家歐商公司在製造『貴夫人 貴公主自動泡咖啡機』,就是那種直接把咖啡豆放到機器裡面,加水之後按一個按鈕就可以煮出一杯好喝的咖啡。該機器在歐美十分暢銷,這家公司想把機器賣到亞洲以拓展市場。有一天業務找到一個台灣的代理商,代理商告訴他:現在在台灣喝咖啡太方便了,而且同類型的泡咖啡機市面上也很多,你這台機器可能會不好賣。但是,現代人都很重視養生,如果你們公司可以讓這台機器也具備『自動煮豆漿』這個功能,那就可以同時滿足喝咖啡與喝豆漿的客戶。如果能做的這樣,那我就可以先下 1 萬台的訂單。

業務想,這可是筆大訂單,反正都是『豆子』,只要把『咖啡豆』換成『黃豆』,再『稍微調整一下線路』,那我們的產品『應該』可以同時具備這兩種功能。於是業務發了封 email 給開發人員:

親愛的開發人員:

有一個大客戶詢問我們的『貴公主自動泡咖啡機』是否支援『煮豆漿』的功能,請幫忙確認是否將咖啡豆換成黃豆之後便可煮出豆漿。如果不行,請評估需要多久的時間可以完成此功能。這是一筆大訂單,客戶急著要,請儘速回覆。
謝謝。

業務 和聲 敬上

好死不死你正好是這個『親愛的開發人員』,收到這樣的 email 要怎麼回?以下是一個失敗的範本:

親愛的業務:

開發人員目前都沒空,無法幫你測試我們的『貴公主自動泡咖啡機』是否可以用來『煮豆漿』。麻煩請找其他的人幫你做這個測試。

開發人員 白木林 敬上

業務看到回信之後很不爽,怎麼可以把即將到手的業績往外推。於是業務就寫了一封信給老闆:


皇上吉祥 親愛的老闆:

臣密言... 我不明白『白木林』為什麼要拒絕我提出的要求,公司的同事不是應該要互相幫忙嗎,怎麼可以回答『開發人員目前都沒空,無法幫你測試這種話呢?眼看有一筆大生意即將談成,『白木林』的作法卻是把生意往外推。我們公司到底還有沒有想要推廣『貴公主自動泡咖啡機』到亞洲?請給予建議。
謝謝。

業務 和聲 敬上 

老闆看了信之後就寫了封信給行銷主管:


親愛的行銷主管:

請評估『煮豆漿』這個功能的市場需求
謝謝。

老闆


以下是行銷人員的回信:


啟奏聖上:

『煮豆漿』這個功能在遠東地區,尤其是中國,台灣,日本,與韓國都有極大的市場。我會協調開發人員,將這個功能加入的我們的產品之中。

吾皇萬歲,萬歲,萬萬歲。

東廠廠公 行銷主管 PLoP 敬上 


接下來的劇情請鄉民們自己發揮....
***

友藏內心獨白:皇上聖明,如果可以再加上『泡茶』這個功能豈不是更好?



2011年2月12日 星期六

除舊佈新 (2)

Feb. 12 09:40~10:40

廢話不多說,寫完之後還要去睡回籠覺。今天來談一下另一個與 architecture 有關的『舊』。

一旦架構設計完畢之後,接下來就是 designers 與 programmers 他家的事,與 architect 無關。Architect 是很『昂貴』的資源,要趕快去接其他的案子賺幫公司賺錢。為了怕 architect 把手弄髒,一律禁止 architect 寫任何一行的程式碼。

以上觀念需要被修正。Teddy 曾經聽過好幾個人提到類似的說法,萬一涉世未深的鄉民們真傻傻照做,那可是陷入萬劫不復的地步。會有這種說法,大體是有人把『software architect』類比為設計建築物的『建築師』。想一想,是不是有些『建案』號稱從國外隨便找個『建築大師』來設計豪宅,一坪隨便就可以賣個一百多萬,真是噱暴了。這些『建築大師』同時間當然是有好幾案子在手邊,而且設計圖畫完之後剩下的就是『施工團隊』的事了,施工這種『小細節』哪敢煩勞『建築大師』操心,人家可是一秒鐘幾十萬上下滴。

依循此種思考邏輯,如果 software architect 也可以只負責『畫設計圖』不用管實做,那就可以同時幫老闆接很多案子,賺好多錢啊。蟹老闆,真是太棒了!所以,software architect 只負責『做設計』,設計完成之後程式寫不出來是 programmers 太遜,絕對不是 software architect 的設計有問題。Software architect 更是不能動手寫程式,因為 coding 這種『沒什麼學問』的事情,只會耽誤 software architect 接更多的案子,賺更多的錢。

***

鄉民甲:講這麼多,那 software architect 到底要幹麼?

首先套句『食神』的話:『只要有心,人人都可以是 architect』。Architect 與 programmer 只是一種角色的區分,誰說 programmer 就不能做架構設計,或是 architect 就不能或不該寫程式?在一個團隊中,當然會有某些比較有經驗的人,負責較多所謂『架構設計』,但不表示其他人就應該放棄所有『架構設計』的權利或機會,僅僅負責所謂『沒什麼學問的 coding 』工作。嚴格講起來,source code 本身才算是軟體設計(請參考 What is Software Design?... 這一篇文章很經典,比起 Teddy 胡扯的文章好太多了,而且可能會改變一個軟體從業人員的一生。在此 Teddy 再次推薦),至於那些畫得『漂漂亮亮的 UML diagrams』只能算是設計過程中的附屬品。想一下,很多建案是不是設計圖的畫得美美的,等到真的住進去才發現,哇靠...近一點看,怎麼主臥室這麼小,格局這麼差。

關於反駁『一旦架構設計完畢之後,接下來就是 designers 與 programmers 他家的事,與 architect 無關』的文章,可參考 Architect-Builder 。接下來談談 architect 該不該寫程式這件事。每次提到這個問題 Teddy 就想到牛頭牌沙茶醬,不對,是想到 Kent Beck 在 Smalltalk: Best Practice Patterns 這本書中所寫的幾句話:

To me, development consists of two processes that feed each other. First, you figure out what you want the computer to do, Then, you instruct the computer do do it. Trying to write those instructions inevitably changes what you want the computer to do, and so it goes. (接下來這一段是重點)

In this model, coding isn't the poor handmaiden of design or analysis. Coding is where your fuzzy, comfortable ideas awaken in the harsh dawn of reality. It is where you learn what your computer can do. If you stop coding, you stop learning.

有些所謂的『系統分析師』或是『軟體架構師』會認為,老子(老娘)好不容易熬到這的地位,當然是奉行『君子動口不動手』的最高指導原則,深怕萬一不小心『動手』就從高高在上的君子變成低低在下的小人。Software architect 也需要 coding 並不是說要跟 programmer 搶飯碗,把全部的需求都做完。但至少要能夠驗證所設計出來的所謂『軟體架構』是可行的。如何驗證?最好是實做一個 architecture prototype 出來。如何實做,阿就 coding 啊。

友藏內心獨白:類似的話題好像講了好幾遍了,真是越老越『雜念』。

2011年2月10日 星期四

除舊佈新 (1)

Feb. 10 21:29~23:16

又是新的一年,以前小時候每到舊年底新年初,老師都會告訴學生要『除舊佈新』,改掉過去一年的壞習慣,立定新年的希望。現在年紀大了,也沒人會跟你講要你『除舊佈新』。想一想這是一件很可怕的事,因為這表示你已經老到『江山易改,本性難移』的階段,只能混一天算一天。

對軟體開發團隊而言,『除舊佈新』也是一件年年都希望達成,卻年年『槓龜』的願望(可能只比中 18 億大樂透要簡單一點點)。因為 Teddy 過年期間在看 Software Architecture: Foundations, Theory, and Practice 這本書,今天就來談一個 Software Architecture 領域最需要被除去的『舊』。

Architecture is a development phase

軟體架構設計是軟體開發(早期)的一個 phase (階段),這個  phase 結束之後,將產生軟體架構設計。大家都知道,軟體架構將主導後續分工與實做的方式,而且軟體架構的修改是一件很大的工程,為了避免在專案進行過程中(coding phase)需要回頭修改軟體架構,在開始寫程式之前,就應該要投資很多時間在軟體架構設計上(big up-front design)。

以上觀念需要被修正。首先, Architecture is not a phase of development(大聲念三次)。為什麼軟體架構設計不是軟體開發的一個 phase?因為軟體開發隨時都在做 architecture design,只是程度多寡的差別。假設你有一個新的專案,預計 20 個 sprints (iterations) 完成。以一個 sprint 兩週來算,共計 40 周(約 10 個月)。如果以傳統 waterfall 的觀點,你在跟客戶預約工作進度的方式大體是:
  • 第1-2 月:需求分析。
  • 第3-4 月:系統(架構)設計。
  • 第5-6 月:程式撰寫。
  • 第7-8 月:測試。 
  • 第9 月:文件撰寫。 
  • 第 10 月:佈署與驗收。
Teddy 不知道現在是否還有人真的依據這種方式來執行軟體開發專案,如果有,相信專案開發成員一定時常有機會問候客戶,業務,PM,或是主管的家人。Teddy 在此祝你好運。

現今的軟體開發流程,不管是比較 heavyweight 的 UP(Unified Process),或是 lightweight 的 agile methods, 都屬於 IID (iterative and incremental) 開發方法。在這種方法之下,不會出現(也不應該出現)architecture phase,不然又回到 waterfall 的老路子。


當然,在專案進行的前幾個 sprints,開發活動中有可能花比較多的時間在確立基本的軟體架構,但這並不是說整個 sprint 除了『設計軟體架構』以外啥事都不幹。而是,舉的例子,前 2 - 4 個 sprint 只完成少數(例如 1 或 2 個) stories,利用完成這些 stories 的過程來逐步確立軟體架構基礎。在軟體架構逐步成型的過程中,陸續增加每個 sprint 可完成的 story 數目。如果專案做到一半,發現原本的軟體架構不足以支撐新的 story,則此時又可以減少該 sprint 完成 story 的數目(因為要利用完成 story 的同時來擴展新的軟體架構,所以該 sprint 可完成的 story 數目就自然變少了)。

大致上就是這個味道,講起來很簡單,但是做起來不容易。看起來採用 IID 好像沒有投資『專屬的時間』在做設計,但事實上 IID 是把設計的時間『打散』到每一個 sprints 中,到專案結束之後,所有投資在設計上的時間反而是更多的。

***

路人甲:為什麼要這麼麻煩?如果一開始不把架構都設計好,怎麼開始寫程式?如果架構是慢慢長出來的,怎麼知道整個系統會不會亂掉,以至於最後要整個打掉重練?


相信許多鄉民們會有和路人甲一樣的疑問,這可能是因為傳統 waterfall 的觀念太成功的深植人心,以至於很多人都『深信』一定要把架構『一口氣全部設計完』才可以開始寫程式。事實上,這個世界上應該沒有什麼『一口氣全部設計完』這一回事。大家都知道的一件事,軟體開發唯一不變的一件事,就是『變』。需求會變,就算是你花了 N 個月設計出一份宇宙無敵,世界無雙的軟體架構,只要需求一變,這份架構就很有可能也許要改變。不服氣的你可能會說,那好,那我就設計一種『可以應付各種改變的架構』...  很抱歉,這種東西在地球上還沒被發明出來。而且一個軟體專案也不可能讓你花太多的時間全部只在『設計軟體架構上面』。在許多情況下,開始寫程式的時間越晚,內心會愈慌亂。Over design (過度設計)的壞處絕對遠遠大於好處。通常 over design 唯一個好處只是營造一種『自我感覺良好』的假象,爽到你(architect),艱苦到我(programmers)。此外, over design 也算是一種『浪費』,應該被消除(請參考 軟體庫存消除浪費 (2):Extra Features )。

當然,要讓軟體架構可以隨著軟體開發『逐步成長』也不是一件容易的事(不然 Teddy 要靠什麼專長混口飯吃)。如果 Teddy 說出等各位累積個 10 年以上開發經驗就可以達到這種境界的屁話,那就遜掉了。Teddy 當然要指點一條明路給各位善男信女們,答案就在前一篇文章中(軟體這條路:Architect 篇 )。什麼,這樣還嫌太麻煩?。好吧,再報一支明牌,去把 Software Architecture: Foundations, Theory, and Practice 這本書的第 4 章 Designing Architectures 看完先,保證功力大增。什麼,都這樣還嫌太麻煩?來人啊,關門放狗....。最後還有一招,花錢請 Teddy 幫你也可以,這樣最快。

***
 
最後提醒一下本部落格的『不忠實觀眾』,如果還沒看過『你的軟體架構有多軟』,趕快回頭補看 。善哉,善哉。

***

友藏『自我感覺良好』之內心獨白:像 Teddy  這麼強的人怎麼都沒獵人頭公司來高薪挖角啊。Teddy 也想賺大錢啊!

2011年2月4日 星期五

軟體這條路:Architect 篇

Feb. 04 01:46~04:10

吃軟體開發這一碗飯(簡稱『吃軟飯』)的鄉民們,到了一定年紀之後,都會遇到同樣的問題:『難道我要寫一輩子的程式嗎?』或是『我還有幾年的程式可寫?』Programmer 雖然不像運動員一樣 35 歲左右就算是『老人』要準備退休了,但是隨著年紀逐漸增長,體力與記憶力逐漸衰退,開始出現以下症狀:程式寫多了肩膀會酸,滑鼠用多了手腕會痛,螢幕看多了眼睛會花,怪打多了血壓會飆高,issues 累積多了頭髮會白,架吵多了口會渴,咖啡喝多了胃會痛,需求變多了心裡會...看...不開...。再加上每天上班忙得要死,寫不完的程式,de 不完的 bugs,根本沒有時間去學習不斷推陳出新的技術。此時不禁想起了潘越雲的『軟體 情字這條路』:


    那會那會同款,軟體這條路,給你走著輕鬆,我走著艱苦
    那會那會同款,軟體這條路,你隴準時下班我留下呷便當
    不願承認加班艱苦年年肖想公司分股票
    不願承認阮的程式A錯誤,不願 test case fail
    那會那會走來,軟體這條路,默默寫著程式,望你看隴無
    那會那會走來,軟體這條路,回過頭才知影,歹走的路途
    不願承認沒照 schedule日日 review 嘛是這離譜 
    不願承認 CI 永遠做不好冬時 release 消息隴無

***

Programmer 的生涯規劃,大體可分為四條路:
  • 累積一定的技術能力之後,轉做 PM,當作客戶與技術人員之間的協調溝通者(PM 動口不動手,讚啦)。
  • 累積一定的技術能力之後,『座艙升等』,從經濟艙(programmer)升等到商務艙(Designer)再升等到頭等艙(Architect)。
  • 轉當 QA Manager。
  • 回家種田。
今天 Teddy 要建議幾本身為一個 software architect 應該要看的書,在這之前,先談一下 architect 要做與不必要做的幾件事。首先是要做的事:
  • 要曾經寫過很多程式。
  • 要參與過多個專案。
  • 要會『畫圖』(至少要會畫矩形,直線,箭頭,還有人)。
  • 要懂得抄襲。
  • 要持續寫『一些』程式。
接下來是不必要做的事:

  • 不用考 UML 認證
  • 不用考 Certified XXX Architect 認證
為什麼不用考認證?原因很簡單,因為 Teddy 也沒去考過...就算去考也考不過...就算是考過設計出來的 architecture 還是有極大的機率不能(好)用, 所以把錢和時間省下來吧。

Teddy 介紹一批 便宜的牛肉  有用的書給各位,鄉民們只要花個『幾年』的功夫把這幾本書看個 70% ~ 80% 這樣也就差不多了。
  1. Design Patterns - Elements of Reusable Object-Oriented Software:有人把 patterns 又稱為 micro-architecture,這本書看熟對於了解各種不同的 architecture styles 很有用,對於寫程式也很有用。
  2. Pattern-Oriented Software Architecture:這一系列的書已經出到 volume 5 了,Teddy 知道大家都很忙也沒那麼多錢把每一冊都買來看。其實只要看第一冊就差不多了可以得知其中的精華,待有錢有閒時再看其餘各冊即可(不看也行啦)。
  3. Patterns of Enterprise Application Architecture:這本書提到很多 Web 應用程式會使用到的 patterns,這些 patterns 在『傳統』的軟體架構或是 patterns 書中比較少看到。有在開發 Web 應用程式的人這本書一定要看。
  4. Software Architecture in Practice, 2nd:這本書的重點可以分為 (1) 介紹 Quality Attributes (non-functional requirements)以及如何滿足這些 Quality Attributes 的方法 (書中稱之為 Tactics);(2) 用 ATAM (Architecture Tradeoff Analysis Method)與 CBAM (Cost Benefit Analysis Method)來分析軟體架構。書中還有很多資料,不過時間有限的話把這兩個重點學會就 OK 了。
  5. Software Architecture- Foundations, Theory, and Practice:這本書是 Teddy 去年八月買的,這幾天才拿出來看(Teddy 內心獨白:我上班也很忙啊)。沒看沒事,一看不得了,真是一本好書。Teddy 正在看第 2 章 Architectures in Context: The Reorientation of Software Engineering 和第 5 章 Connectors。寫得真好,如同書名副標題一樣,要理論有理論,要實務有實務,而且是 2010 年出版的新書,內容也比較新。這本 700 頁的書很適合拿來當教科書,想要了解 software architecture 這個領域的地形地物可以先看這本書。把它當地圖看,不用嘗試將書中的內容全部記下來。
以上這五本能夠看完就很厲害了,介紹太多也沒人有時間去看。最後以第五本書第 2 章 (p. 24) 的幾句話當作結尾:

  1. Every application has an architecture.
  2. Every application has at lease one architect.
  3. Architecture is not a phase of development.
***

友藏內心獨白:祝鄉民們兔年 test cases 寫到吐。