l

2013年11月30日 星期六

2012緬甸考察之旅Day4-B到達敏貢順便吃午餐

Nov. 27 15:01~15:43

9:00 AM準備開船,大部分的遊客都選擇坐在視野比較好的上層甲板。船行時間約一小時,下午一點要搭同一艘船回航,等於在敏貢只有不到三小時的時間,還真有點趕,不知為什麼要那麼早返航啊。

伊洛瓦底江的江面非常寬廣,航行在江上的船也不少,很是壯觀。不過Teddy多年前第一次到緬甸的時候,從蒲甘搭船逆流而上達到曼德勒,一路上已經連續看了超過12小時的伊洛瓦底江,所以此次搭船就比較淡定一點挑眉質疑

螢幕快照 2013-11-27 下午3.32.22

螢幕快照 2013-11-27 下午2.59.32螢幕快照 2013-11-27 下午3.00.05螢幕快照 2013-11-27 下午3.00.21螢幕快照 2013-11-27 下午3.00.44螢幕快照 2013-11-27 下午3.01.01螢幕快照 2013-11-27 下午3.01.45螢幕快照 2013-11-27 下午3.02.05螢幕快照 2013-11-27 下午3.02.17螢幕快照 2013-11-27 下午3.02.52

螢幕快照 2013-11-27 下午3.33.29

 

即將到達敏貢,下列第一張照片就是著名的敏貢塔。河岸邊船隻和鄉民們不少,還有小朋友等待觀光客的到來,以及在河邊洗澡的鄉民們。

螢幕快照 2013-11-27 下午3.14.00螢幕快照 2013-11-27 下午3.14.41螢幕快照 2013-11-27 下午3.15.05螢幕快照 2013-11-27 下午3.15.18螢幕快照 2013-11-27 下午3.15.30螢幕快照 2013-11-27 下午3.15.52螢幕快照 2013-11-27 下午3.16.05螢幕快照 2013-11-27 下午3.16.26螢幕快照 2013-11-27 下午3.16.55

 

下船的時候要小心一點,可不要跌落伊洛瓦底江啊。

螢幕快照 2013-11-27 下午3.17.16

***

下船之後有點小迷路,繞了一下子看到河邊有一家餐廳,肚子也有點餓了,在這裡簡單吃的午飯順便上個廁所挑眉質疑。不用這裡的餐點真的…嗯,還蠻普通的,再加上時間真的不多,應該直接殺到敏貢塔才對啊。

螢幕快照 2013-11-27 下午3.27.20螢幕快照 2013-11-27 下午3.27.41螢幕快照 2013-11-27 下午3.27.58螢幕快照 2013-11-27 下午3.28.09螢幕快照 2013-11-27 下午3.28.18螢幕快照 2013-11-27 下午3.28.31


***

友藏內心獨白:食物普普,但江邊的view很棒。

2013年11月29日 星期五

[工商服務] 2014年1月Scrum課程開放報名

Nov. 28 15:37~16:20

螢幕快照 2013-11-28 下午3.02.39

 

台灣的工程師真的很可憐,以前加班熬夜導致爆肝,最近又有大老闆批評「工程師沒有換腦袋」。在台灣當工程師一定要搞到「換肝」and「 換腦袋」的地步,不然就只能選擇「換老闆」?難道沒有其他更好的做事方法提升大家的競爭力嗎?

有的,就是敏捷開發方法。

Scrum敏捷開發方法在國外早已成為主流的軟體開發方式,近幾年在國內也漸漸受到關注。很可惜我們台灣人「體質特殊」,在引入一種新方法的過程中,往往遭遇到來自於本地文化、公司政治、客戶、團隊合作、個人技術能力等各種不同面向的挑戰,而導致實施成效不彰。

是方法本身不適合台灣環境特性呢,還是實施的過程中沒有做對、做好?

原來是沒有找到對的人來傳授練功方法。還有沒有救?有,新年新希望,想改變現狀的朋友們歡迎參加第八梯次「Scrum敏捷方法實作班」,開課日期為2014年1月11、12日(週六、週日),課程報名網頁在此

課程特色:

  • 任何人都可以上:不限軟體開發人員,只要想要了解Scrum的朋友們都可以報名參加,包含大老闆、專案經理、產品經理、介面設計師、工程師、技術經理等。
  • 由Teddy負責授課:在歡笑聲中不小心就學會了Scrum。
  • 最符合台灣現況的Scrum導入經驗由Teddy在課程中分享不同產業導入Scrum的成功與失敗經驗。
  • Scrum活動實作課程搭配大量的練習活動(產生product backlog、sprint planning meeting、task break down、task board建立、daily scrum、retrospective meeting等) ,讓學員們在課程結束之後具備實際帶領Scrum團隊的基本能力。
  • 小班分組模式課程搭配實際帶領過Scrum團隊的助教,協助各組練習各項Scrum活動。
  • 贈送Scrum工具包課程推廣期間贈送一組Scrum Master必備的Scrum工具包,讓學員上完課之後可以帶著工具包立即協助團隊導入Scrum。
  • 售後服務上課學員可加入Facebook上專屬的「泰迪軟體敏捷開發課程社團」,課後有任何問題皆可在此發問。

課程進行方式請參考:

 

詳細課程說明資料請參考報名網頁

***

友藏內心獨白:開頭搞得好像在賣藥一樣。

2013年11月28日 星期四

學校沒教、主管不懂、同事不會、自己沒空學的Design Pattern

Nov. 27 11:16~13:35
image
圖片來源在此

今天這個標題有點「欠扁」,不過這是因為這兩天發生的兩件事剛好讓Teddy有這種體會。

埋下種子
昨天下午應邀到某校資工系介紹design pattern,一講就是三小時,幾乎把「設計模式這樣學就會了:入門實作班」的第一天課程,扣除pattern寫作練習與Singleton模式以外的內容講完。在演講開始之前和邀請者王教授聊了一會。

王教授:你在外面開了很多課程,每一門課我都很想去上啊。

Teddy:謝謝(傻笑…)。

王教授:不過課程費用不便宜啊…

Teddy:Orz……(Teddy內心獨白:一分錢一分貨,而且我可是「燃燒生命」在授課的啊XD

***

以上對話片段不是重點,重點是王教授說他日後想要開design pattern的課程,雖然design pattern已經「問世」快20年了,而且在業界也是非常實用與需要的一門技能,但是很遺憾國內大學資訊相關科系教授這門課的並不多。就Teddy所知,北科大(Teddy的母校)可能是國內最早教授design pattern的學校之一,時間可以追朔回10幾年前(關於這一點,Teddy也有一些小小的貢獻XD)。

王教授希望Teddy利用短短三小時的時間,在同學心中「埋下一顆design pattern的小種子」,日後可以引發學生學習design pattern的興趣。

如果鄉民們只有三個小時,請問你會選擇介紹GoF書中23個pattern的哪幾個?答案是,一個都不介紹。既然是要埋下種子,就要追本溯源,探討design pattern的源頭思想,也就是Alexander在他的《The Timeless Way of Building》以及《Notes on the Synthesis of Form》書中所提到的pattern方法。

演講的內容Teddy早已公開在此,之前也談過好幾次了,就不再重複。Teddy想說的是,市面上比較流行的design pattern中文書籍,例如以下幾本,並沒有介紹Alexander的方法,這是Teddy覺得比較可惜的地方。

螢幕快照 2013-11-27 下午12.02.16


埋好種子
Teddy目前發現唯一一本談論比較多Alexander方法的設計模式書籍,就是《Design Patterns Explained,2nd》,這本書出版至今也有10年了,很多年前第一版有翻譯成正體中文版,事隔10年之後最近博碩出了第二版的正體中文版。身為pattern愛好者自然買了一本回來看一下,前天拿到書稍微翻閱一下,大體上還OK,但有些小地方如果改善一下,可以減少一些讀者的誤解。

螢幕快照 2013-11-27 下午1.28.21


這本正體中文版很明顯就是從對岸簡體中文版轉過來的,書中有不少對岸的用語。不過這一點其實還好,不算什麼大問題。畢竟現在台灣從對岸接收太多的資訊,很多對岸用語,例如「優化」、「高清」、「編程」、「洗洗睡」,也慢慢地快變成「台灣本地用語」了挑眉質疑。語言的演變本來就是如此,不需要過於排斥。

Teddy小失望的地方是書中談到Alexander方法的一些細節,例如:
從背景設計原則(214頁)

光看這句中文Teddy真的想不起來Alexander有提到「從背景設計」這種原則,這句話聽起來感覺是在寫電影劇本的時候會用到的技巧挑眉質疑。對照英文版才發現,原來是「The Principle of Designing from Context」。Context這個字在Alexander方法裡面佔有重要的地位,書中將Context翻譯成「背景」,感覺有那麼一點怪怪的。

Context真的不好翻,「The Principle of Designing from Context」不翻譯的話意思反而比較清楚,如果真的要翻,用「以脈絡為設計起點的原則」,並加上英文,可能會好一些。

***

Christopher Alexander將此稱為「複雜化」—一種從最簡單(概念性)的層次開始,然後逐漸增加細節和特徵,隨著逐步深化,設計也漸趨複雜的過程(215頁)。

對照英文版的說明:Christopher Alexander called this "complexification", the process of starting at the simplest (conceptual) level and gradually adding details and features, making the design more complex as you go deeper.

兩相對照翻譯並沒有什麼問題,但Teddy看到這裡一時也想不起來Alexander的書中有特別提到「複雜化」這件事。奇怪了,敏捷開發告訴大家設計不是要儘量「簡單化」嗎,怎麼Alexander提倡「複雜化」?再往上追一層,看到Alexander在《The Timeless Way of Building》第370頁的講法:

This is a differentiating process.

It views design as a sequence of acts of complexification; structure is injected into the whole by operating on the whole and crinkling it, not by adding little parts to one another. In the process of differentiation, the whole gives birth to its parts; the parts appear as folds in a cloth of three dimensional space which is gradually crinkled. The form of the whole, and the parts, come into being simultaneously.

Teddy以前讀到Alexander書中這一段話的當下只把differentiating這個字記下來,並沒有特別去記憶complexification,因為光是講complexification很容易引起誤會。

Teddy拿到《Design Patterns Explained,2nd》中文版(《設計模式的解析與活用》)的時候是跳著看的,後來才注意到在上面這段話之前,書中第12章,184~185頁有對「複雜化」加以解釋,讀了這一段解釋之後讀者比較不會產生誤會。也許在215頁加個注釋,說明一下「複雜化」的觀念可以參考184~185頁的說明,這樣可以減少一些不必要的誤解。

***

從Alexander的方法來學pattern,可以看到許多光從GoF或是其他書籍所學不到的見解,廣義的來說,學會這套方法對於「設計」任何產品都有助益。要會學Alexander的方法,最快的方式就是來上Teddy的「設計模式這樣學就會了:入門實作班」與「設計模式這樣學就會了:進階實作班熱戀

***

友藏內心獨白:學習絕世武功沒有人指點一不小心真的很容易走火入魔的說。

2013年11月27日 星期三

找不到資料要傳回Null還是丟出Exception?

Nov. 25 13:12~13:58

image

 

上禮拜Teddy到某校資訊系演講,講題一樣是「例外處理設計與重構」。在演講中Teddy舉了幾個語言例外處理的壞味道,例如return code與ignored checked exception等。Teddy建議在還不知道例外要如何處理的時候,不要去捕捉、隱藏、忽略例外,此時應該採用fail-fast策略,丟出例外並且讓程式終止。

演講結束之後有一位同學問了Teddy一個問題…

同學:你剛剛建議我們不要用return code來代表例外,假設我要設計一個依據學號到資料庫中查詢學生資料的函數。如果找不到符合條件的學生資料,是不是應該要丟出例外?

Teddy:不一定,這要看你的需求與設計。假設你的function長成這樣public List<Student> queryStudents(String ID),傳回一個大小為0的List就可以代表找不到學生資料的情況。

同學:那如果我的function只會回傳一個學生物件呢?

Teddy:假設你的function長成這樣public Student queryStudent(String ID),只傳回一個物件,那麼你就要問自己:「依據ID來尋找學生資料,但最後找不到任何一筆符合條件的資料」,這種情況,算是正常狀況還是異常狀況?

同學:…

Teddy:如果你問我的看法,我會覺得這是正常狀況。在日常生活中,依據某些條件去找資料,最後找不到任何符合條件的資料,算是一種很常見的狀況,所以我不會針對這種情況丟出例外。所以你可以傳回null用來代表找不到任何資料,如果不喜歡null,也可以套用Null Object設計模式,傳回一個Null Object來表示找不到符合條件的資料。

***

同學所問的問題,可以用下圖來解釋。Exception在程式語言中用來代表error與failure,分別表示「目前可能處在不正確的狀態」與「被呼叫的服務或函數辦事不力」。「找不到資料」並非狀態錯誤,也不是尋找資料的函數辦事不力。事實上,尋找資料的函數正確執行完畢,只不過沒有找到符合查詢條件的資料罷了。這種狀況是在規格中所允許的狀況,和例外處理無關,只要在設計介面的時候規定好傳回某種特殊值(null 或Null Object)代表找不到資料這樣就可以了。

螢幕快照 2013-11-25 下午1.42.56

***

友藏內心獨白:有人問問題,講者心中應該要放鞭炮了。

2013年11月26日 星期二

估的準,因為我加班?!

Nov. 025 10:02~10:50

image

 

有人問Teddy關於Scrum的問題…

有人:我們在估算story point的時候遇到很多問題。

Teddy:什麼問題?

有人:因為團隊成員經驗不足,所以story point估不准。

Teddy:何謂估不准?

有人:就是預估得太樂觀,story會做不完。

Teddy:然後哩?

有人:然後大家只好「主動加班」把story做完,以便在sprint review的時候可以demo這些原本預計要完成的story。

Teddy:為什麼要加班完成所有story?

有人:如果沒做完,團隊成員會覺得自己「辦事不力」,可能會被主管拿出來檢討。應該說,大家「責任心太重了」。

Teddy:嗯,很特別的觀點。所以…你說你們在採行Scrum?

有人:對啊。

***

上述「有人」跟Teddy對話的情境,剛好讓Teddy想到另外一個案例。有位主管告訴Teddy,他想到一個「考核」員工有沒有認真實施Scrum的方法:「只要連續兩個sprint沒有完成所有預估的story,這個團隊就要解散。」這種規定讓Teddy想到以前很多台灣的大專院校都有著「連續兩學期被當學分達1/2就要勒令退學」的規定一樣,拿來套用在Scrum團隊上面,真的是太有創意了挑眉質疑

有創意歸有創意,但這樣行得通嗎,有辦法解決所謂的「估不準」的問題嗎?

談到「估不準」,要先判斷一下,「估不準」到底是一個「問題」,還是一個「症狀」。Teddy認為「估不準」只是一個症狀,隱藏在此現象背後的問題,可能是:

  • PO根本沒來參加sprint planning meeting,或是沒有充分準備好story就來參加會議。因此,無法當場解答團隊成員對於需求的疑問。
  • 在估算的時候團隊成員根本沒有溝通,出牌變成一種形式,大家只想趕快結束sprint planning meeting。
  • 估算過於樂觀,低估了風險與不確定性。
  • 團隊的領域或技術能力不足,但卻又沒人願意承認這個事實,大家都假裝沒有問題,不願意向團隊成員求助。
  • Sprint進行中團隊成員遇到需求的問題找不到PO可以詢問。
  • 工作環境太差,過於吵雜、電腦太慢、螢幕太小、測試設備嚴重不足。
  • 敏捷開發實務做法沒有做到位,例如根本沒有撰寫單元測試,也沒有實施持續整合。
  • 跨部門溝通難如登天。
  • 團隊根本沒有訂定DoD(Definition of Done),所以團隊成員不知道到底怎樣才算「做完」。
  • 在sprint進行中,團隊成員一直被中斷,難得有完整的時間可以用在開發上面。
  • 其他另外100種理由…

***

Teddy認為,估算的目的主要在於凝聚共識,儘量消除團隊成員腦袋裡的眾多的「問號」,讓團隊成員知道接下來一個sprint要做什麼(what)以及要怎麼做(how)。既然是「估算」,和最後的「實際狀況」多少一定都有誤差。如果一開始導入Scrum就不想去面對這些「誤差」,而是一味的粉飾太平,假裝「估算=實際」,如此一來就失去了改善的機會,只是穿上Scrum外套但骨子裡還是用傳統方式來進行軟體開發的活動。

關於估算的問題,也可以參考〈這是電腦估的喔〉這一篇。

***

友藏內心獨白:一種Scrum,百種解讀。

2013年11月25日 星期一

Java的try、catch、finally(8):例外處理失敗怎麼辦?

Nov. 18 16:35~17:35

image

上禮拜六「第二梯次例外處理設計與重構實作班」課程中,有一位學員問了Teddy一個問題…

學員:你上課的時候提到catch block的責任之一是負責「錯誤處理(error-handling)」,也就是說如果系統狀態不對了,要想辦法將系統恢復到一個正確的狀態。

Teddy:對啊。

學員:我們之前有遇到一個錯誤處理的問題,團隊成員和主管討論了很久都沒有結論。

Teddy:什麼問題?

學員:如果錯誤處理的程式也發生錯誤,那該怎麼辦?

Teddy:很簡單,三秒鐘就可以回答你。如果錯誤處理的程式也發生錯誤,無法將系統回復到正確的狀態,就丟出一個ErrorHandlingException來代表這樣的異常狀況。

***

上述問題可以用下列例子來思考。有遊客在海邊溺水發出求救訊號(丟出例外),這時候「救生員」(例外處理程式)要去搶救這位溺水的遊客。如果救生員搶救失敗,自己也溺水了,那怎麼辦?

  1. 假裝什麼事都沒發生,把求救訊號(例外)吃掉。
  2. 繼續向外發出求救訊號。

現在答案就很明顯,應該是要選2,繼續向外發出求救訊號。但是接下來還是有一個問題需要考慮,那就是例外蓋台的問題:

  • 如果救生員直接發出ErrorHandlingException,那麼這個例外會覆蓋掉原本遊客溺水的例外,產生「例外蓋台」的問題。

所以說,這個ErrorHandlingException應該成為一個suppressed exception,被加入到原本遊客溺水的例外身上(代表遊客溺水的例外在這裡稱為function failure

***

下圖說明了當例外處理失敗(包含cleanup失敗)的時候要如何處理的作法。

image

 

簡而言之,鄉民們需要:

  • 自己定義ErrorHandlingException、FaultHandlingException、CleanupException、這三種runtime exception。
  • 如果catch block需要做error-handling或是fault-handling的工作但卻失敗了,則產生ErrorHandlingException、FaultHandlingException來表示這種例外狀況。
  • 如果finally block需要做cleanup的工作但卻失敗了,則產生CleanupException來表示這種例外狀況。

寫到這裡鄉民們可能會想:「丟出了ErrorHandlingException、FaultHandlingException、CleanupException難道就沒事了嗎?要不要在caller的程式碼中去處理這些例外?」

這個問題要看鄉民們對於程式強健度的要求有多高,以及這些例外產生的機率。雖然「理論上」程式運行的時候有可能會發生ErrorHandlingException、FaultHandlingException、CleanupException,但「實際上」這些例外發生的機率與頻率有多高,有時候在設計階段並不容易預測。如果針對每一個function或是method都要去思考要如何處理它們「可能」會丟出來的所有例外,那麼可能會造成不必要的過度設計,浪費太多資源。在這種情況下,開發人員只要確定:

  1. 所有的例外狀況都有被回報。
  2. 回報語意清楚的例外,以便協助開發團隊縮短事後除錯時間。

這樣的例外處理策略就可以應付大部分的情況,也可以避免過早且過度設計例外處理方法的問題。

***

友藏內心獨白:例外處理的例外,還是例外。

2013年11月24日 星期日

2012緬甸考察之旅Day4-A徒步至往敏貢搭船處

Nov. 11 18:40~19:07

今天要搭船去敏貢(Mingun),來回預計需要花上一整天的時間,所以就沒有租汽車。看了一下地圖,住宿地點離搭船處「看起來」不遠,決定早上走路去。

螢幕快照 2013-11-11 下午6.43.40

 

早上快8點的時候從旅館出發,大概8:40左右達到。一路上看到不少吃早餐的鄉民,還有身穿紅衣沿街托缽的喇嘛。

螢幕快照 2013-11-11 下午6.46.18螢幕快照 2013-11-11 下午6.46.57螢幕快照 2013-11-11 下午6.47.06螢幕快照 2013-11-11 下午6.47.18螢幕快照 2013-11-11 下午6.47.30螢幕快照 2013-11-11 下午6.47.39螢幕快照 2013-11-11 下午6.47.50螢幕快照 2013-11-11 下午6.48.23螢幕快照 2013-11-11 下午6.48.39螢幕快照 2013-11-11 下午6.48.49螢幕快照 2013-11-11 下午6.49.02螢幕快照 2013-11-11 下午6.49.17

 

下面中間這張照片,有一個黃色大門的地方,好像是當地的遊樂園,搭船的地方就在不遠處。

螢幕快照 2013-11-11 下午6.49.27螢幕快照 2013-11-11 下午6.49.39螢幕快照 2013-11-11 下午6.49.54

 

走下階梯就來到河邊購票處,感覺應該是國營事業。

螢幕快照 2013-11-11 下午6.58.38

 

買船票要先拿出護照登記,印象中船票一律是來回票。去的時候搭哪一艘船,回程還是搭同一艘船。

螢幕快照 2013-11-11 下午6.58.09螢幕快照 2013-11-11 下午6.58.46

 

河邊景色,許多老外和Teddy一樣,在等著船開。還有很多當地小朋友會跑過來要東西。

螢幕快照 2013-11-11 下午6.50.05螢幕快照 2013-11-11 下午6.50.19螢幕快照 2013-11-11 下午6.50.34螢幕快照 2013-11-11 下午6.50.43螢幕快照 2013-11-11 下午6.50.57螢幕快照 2013-11-11 下午6.51.16螢幕快照 2013-11-11 下午6.51.35螢幕快照 2013-11-11 下午6.51.43螢幕快照 2013-11-11 下午6.51.57

 

螢幕快照 2013-11-11 下午7.02.37

螢幕快照 2013-11-11 下午7.03.00

螢幕快照 2013-11-11 下午7.03.37

***

友藏內心獨白:非常特別的搭船經驗。