2016-12-21

[筆記] User Story Mapping in Agile Tour Taipei 2016



這場session的講師是Erica 

Erica一開始先玩個有趣的破冰遊戲
給每個人四格的紙
每個人先在第一格寫上你想做的事
接著將紙傳給左邊的人
左邊的人要看著第一格 “你想做的事”

將 它 畫 出 來 !!!

畫在第二格
再傳給左邊的人

第三個人 是看著第二格的圖
在第三格 寫下圖的描述
再傳給下一個人

第四個人 是看著第三格的描述
在第四格 畫出來



大家可以猜到這在玩什麼嗎???


藉由有趣的破冰遊戲
也稍微帶到了今日的主題

如果只是靠文件 沒有溝通
那大家還是會誤解原意

重點是 有沒有對話


接著就開始帶著大家來體驗User Story Mapping了
一樣藉著活動
將有共同興趣 或是 共同目標的人分組
接著 這群有共識的人 一起討論

如果你是出國旅遊
當你 決定出發出境
會有什麼步驟 ?


這些步驟 必須透過 動詞名詞 的方式呈現
每個步驟都寫在便利貼上

1st Round大家先把手裡寫的 手忙腳亂地貼在白報紙上
因為題目很明顯是時間軸
所以我們從左邊開始 按照時間順序 依序往右貼
這過程中也充斥著團員們的衝突
例如 我習慣先決定機票 再決定日期
但是大部分的人是先決定日期 再決定機票
不過最後達成共識就好啦


歸類

亂亂的順序當中 總有幾項是可以Group起來的
所以我們大概分類了
1. 預約事項
2. 調查資料
3. 準備行李
4. 動身出發

而這些分類 (Activity) 就是整個故事的骨幹
而這些骨幹下的小故事 
就是 
整個故事的細節

2nd Round
假想 過程中 如果有某個環節出問題 你會增加或減少哪些故事呢?

3rd Round
假想 如果你是某種身份的話 你會增加或減少哪些故事呢?
我們這組就是假想我們是美食部落客
所以我們在
(1)預約事項中增加了 “敲定餐廳合約”

(3)準備行李中增加了 “攜帶胃腸藥品”

4th Round
假想 如果你是當天來回 你會增加或減少哪些故事呢?
把最少故事能滿足當天來回的需求的故事留在第一水道


於是我們就假想我們是出差客 一切簡便
省去一堆預約行程跟行李

有點像是 內褲版本的產品 你可以把它想成 MVP
其他故事當然不是拿掉 而是下移到第二水道
在User Story Mapping中 就把多餘的故事往下移
這第二水道則是稍微充裕之後可以滿足的需求

經過這個 User Story Mapping Workshop
我學到了 初期我們必須盡量把想法拋出來
然後 歸類
這個類別就是骨幹
骨幹是AND的概念
我做完 類別A 會做 類別B Then C
而骨幹下的細節
是 OR 的概念
為了完成類別A
我可以做 x or y or z

接下來的發現 其實不會脫離這個骨幹
然後盡量以不同角度 去發想 是否還有故事
最後找到最小執行Effort的MVP -> See it work
以及行有餘力還能完成的其他故事 -> Make it better
最後再補強 -> Make it releasable

User Story Mapping 畫完之後
它的價值在於
透過故事 開啟對話

整張地圖 要放在可視的地方
視覺化的方式 讓團員一目瞭然目前的Roadmap

不過 對於時間軸這個概念
其實我還有些疑惑
如果有些需求 其實沒有時間的概念呢?
先做什麼其實無所謂 那軸線將會是用什麼方式呈現呢?

另外 Erica 有提到
User Story Mapping 的缺點是 主題已經事先定好了
所以如何補強這一點呢?
可以考慮 
Design Thinking 跟 Thinking Impact

[補充]
建立User Story Mapping的六個步驟

2016-12-18

[筆記] ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 in Agile Tour Taipei 2016

這個Session是在講

引導

講師是Yves
好的引導 應該是引導流程
讓參與者在無形之中被引導了

而Scrum Master 不應該時時刻刻跟大家說要做什麼
而是要引導活動
透過活動 引出團員的想法或行動
所以Scrum Master 必須夠中立 以第三者的角度切入

[jug] 我也深感這種中立的角色 引導Member講出自己的結論 會比以往直接由上而下的Command來得有效

[jug] 深深記得在Daniel在CSM的課說過 Scrum Master就像牧羊犬 對團隊守望

評估團隊目前的問題
可以使用 CDE Model

C : Container
D : Difference
E : Exchange

Container : 容器 可以想像成範圍, 物理空間, 定義的問題等等

然後準備繪出四個象限

Difference : 水平軸線 最左邊代表差異大 最右邊代表差異小

Exchange : 垂直軸線 最上面代表交流多 最下面代表交流小

想像容器的問題 會位於四個象限中的哪裡

你就知道目前團隊的問題位於



左上方 D+E+ : 討論半天 雞同鴨講

左下方 D+E- : 開會沒意見 會後講不停

右上方 D-E+ : 人人都贊成 執行很難成

右下方 D-E- : 你說你的 我滑我的

接著各組討論 依各個目的
大家可以看看每組的討論內容

不過對我來說
最感興趣的是 如何增加交流 

把問題丟給member
好好的引導
member自然就討論出一堆Action Item了

你看講師 什麼也沒教我們
我們自己就討論出Solution了 XD

補充
引導的技巧

其中我最喜歡的兩張圖
對稱的溝通 = 高生產力

頻繁跨團隊溝通 = 高創造力


我們目前的團隊非常需要這兩種特性
Cross-site, Cross-project, 甚至是Dev & Ops Team
希望未來能夠高生產力 & 高創造力

講師的slide

[筆記] 乘著Agile的風 往CD的方向 in Agile Tour Taipei 2016





這個Session描述著一個沒有Agile實踐的團隊 怎麼一步一步地邁向CD之路
講師是 Edward
首先講者準備了一組 成熟度模型
用來評估目前團隊的成熟度
幫助組織了解目前團隊的開發流程距離CD這條路還有多遠

[五大指標]
(1) CI
(2) Automated Deployment to env
(3) Test Automation
(4) Version Control
(5) Agile CD
[判斷準則]
(1) 流程無法重複使用
(2) 有流程可參考 部分自動化
(3) Agile 開發流程中有自動化
(4) 流程可視並趨勢追蹤
(5) 流程最佳化處理

而以下是講者一步一步地讓團隊走向CD的步驟
我個人覺得超有感 因為我們現在也是很不DevOps 手活還是很多
阻塞了整體的速度

Step 1 : Local的 automation script 
(要先有script 再上CI 才有意義)
(後來 Open Space跟朋友聊這塊 也有人分享說 先上Local 對Member心理上是安全的)

Step 2 : CI
透過Jenkins來跑Step 1產生的 Local Script

Step 3 : Version control
[jug] 這點我覺得怪怪的 Version Control 不是應該是Step1嗎

Step 4 : 自動化部署
參考一下 : ios-deploy, facelane, fabric(remote deployment)

Step 5 : 開始跑 Non-functional test
定義 Monkey Test

Step 6 : 可視化
讓大家都知道 目前的狀態
    (1) Slack (透過slack 通知大家狀態)
    (2) Pipeline (Jenkins PipeLine 一目瞭然)
    (3) JIRA (issue tracking)

如果大家都裝死不看?(狼來了效應)
可以用聲音通知大家

Step 7 : 團隊快速溝通
(1) 快速開發
(2) 快速調整整合需求
(3) 快速測試 => [3A] Anyone, Anytime, Anywhere
(4) 快速改進 不要放棄 => Retrospective

講師有句話說得真好 我非常認同
*** Retrospective 做得好 開發沒煩惱 ***


補充3A測試的部分
可以透過 Slack bot 跟 Jenkins整合
讓人人(非QA) 能夠自己呼叫 slack bot 去做測試 不用再麻煩QA
Slack bot的好處 就是隨時隨地任何人 透過Slack Bot下指令去工作
能自動化的地方就自動化 手工的部分還是越少越好
這也是我的目標

*** Test as a Service (3A + 2A) 3A + AnyDevice + AnyAutomate ***

講者最後提到了 Test as a Service
跟我最近跟一些團隊接觸的經驗頗像

另一方面 由於講者是出自於StartUp Team
所以工具都是找免費的資源
這點可以好好參考

參考資料:
The Continuous Delivery Maturity Model
上面這串是CD的成熟度模型評測 可以拿來評評看自己的團隊喔

PS. 講師的投影片 如果有放出來 我再補上

2016-12-09

Scrum Drawing Game 1.0

[前言]
事情是這樣的 約莫11月初的時候 我的老闆找我談了一下
在年度盛會ETS Global Meeting上是否能準備一個Workshop ?

原本手頭上有兩個已經帶過的workshop 但是都太專門太技術
不太適合ETS 所有的Member

所以我想了又想 想了又想 想了又想
終於在有一天的夜裡

想到了一個很棒的Idea

Scrum Drawing Game 



[設計思維]
在設計遊戲的時候
我站在User的角度去思考
經由這個Workshop 我能學到了什麼

於是我把可能可以學到的項目都列出來:
1. 悶著頭做 可能到最後方向錯誤 不是客戶要的
2. 什麼叫做可以出門的產品
3. Business Value 的重要性
4. 基礎建設的重要性
5. 及早交付的重要性
6. 隨時調整PBI優先順序
7. 隨時整理Product Backlog
8. Retrospective 的重要性
9. 如何達成共識
10. PBI的描述越清楚 越能幫助Team完成任務

所以我設計了以下幾種規則 讓學員能夠體認到上述能學到的觀念
1. 每個Sprint都要Review 隨時檢視
2. 垂直性功能而非水平性功能, 一個角色的完成 一定要有基本的外型,姿勢, 顏色, 位置才能出貨
3. 每個圖畫中的角色都有不同的Business Value
4. 如果完成的基礎建設 可以加快開發速度
5. 越早完成部署 越早拿到好處 賺到的錢會加倍
6. 根據Business Value 調整優先順序
7. 一定要隨時調整Product Backlog 不然你會跟不上
8. 如果能停下來 做個自省 找到改善方法 會比不自省來得好
9. 面對面 隨時討論 隨時也能找PO Sync
10. 訓練PO的邏輯與描述能力

[遊戲流程]
== 產出 ==
一張圖畫


== 隊員分配 ==
每組一個 Product Owner
其他人皆為 Team

== 這個遊戲總共 4 個Sprint ==
每個Sprint 約莫30 分鐘
15 分鐘 做 Plan & Run
10 分鐘 Sprint Revew (all groups)
 5  分鐘 Sprint Retrospective

== Sprint 0 ==
在Sprint 0 , Team 要先準備一張紙版的JIRA
要分成這四個欄位 : Product Backlog, To Do, In Progress, Done

PO 這時要去理解 User想要的圖案是什麼
然後將需求轉化到 Product Backlog

PS. 此時Team可以先幫忙PO把PBI建立起來

== Sprint Start ==
== In the Sprint Planning ==
大家一起討論 要先做什麼
PO 要盡量釐清需求 也要考慮Business Value 也要考慮是否要實作基礎建設

估算出來的Sprint Backlog 要將這些Story貼到 Todo欄位


== Run Scrum ==
PO 這段期間內 要隨時refine PBI 隨時調整優先順序
Team 就按照Story 工作 (new feature or infrastructure)

基礎建設完成之後 隨時可以得到一把剪刀 跟 20%Sample的拼圖

PS. 我安排的基礎建設是 "數獨" 正常會吃掉1~2 Sprint的時間 就看團隊願不願意投資


== Sprint Review ==
1. Demo這個Sprint的產出
2. User 根據產出 不同角色有不同價值 圖案只要超過某個條件 就能拿到價值
2. 其他組可以趁機來觀察一下別組靠什麼賺錢

PS. Feedback要整合進Product Backlog


== Sprint Retrospective ==
檢討 找出改善方案

== Repeat the process ==
重複這個循環直到第四個Sprint結束







[發現]
1. 一開始有幾組先把所有的角色的草圖畫出來 但是沒能得到分數 因為這東西不能出門 (MVP)
2. 由於越早交付 價值的倍數越大 所以應該要先拼提早交付的
3. 狂做基礎建設的組別 得到很多拼圖 交付的產品馬上就趕上來了
4. 目前沒有一組有觀察到User喜好 而隨時更改Story 有點可惜
5. 果然面對面溝通是最有效率的
6. 如果有Member卡住 換人畫畫看


[自省]
1. PO到最後都是在Sprint期間 邊看sample邊描述 提醒member哪邊做錯了
    [S] 1. PO待planning結束得先暫時離開group
           2. PO只有在planning時才能說話

2. 重複計分的問題
    [S] 做分數條 打過得分數就貼在上面

3. 剪刀功用不大
    [S] 其實原本的設計是希望學員把圖給剪下來 再貼到白報紙 這樣才會造成預期的塞車

4. 資源太充足
    [S] 1. 隨機抽走一個人
           2. 一開始白紙太多 或許只需要3,4張 其他用數獨去換

5. 大家都沒在看別人畫了什麼 得了幾分
    [S] TBD

6. 大家都沒做planning或是retrospective 直接繼續埋頭做事
    [S] 強制設下 planning跟retro時間 不做的人就發呆

7. 這個題目的需求是死的 一開始PO看到的sample 是什麼就是什麼 下次可以模擬需求是會變的
    [S] TBD


[看看大家的作品吧]






2016-11-15

Relative Estimation - Bathing Animal Workshop

今天則是受邀向tool team介紹 Relative Estimation
如何讓成員快速理解這種新估算模式呢?
最好的方式就是workshop了
於是我把專業的動物洗澡團隊又搬了出來
假設我們是個動物園團隊
今天要評估幫動物們洗澡的Effort

今天的動物共10隻




每個動物都有不同的需求
例如 :
石虎是個動物園明星 全台僅剩一隻 要小心呵護
銀背大猩猩是全動物園最兇猛動物之一 要剪指甲
等等

Product Owner 今天就是負責將這些需求天馬行空地描述出來
其他Member 則是依據這些需求 來做估算



估算的步驟 :


Step 1 : 比較大小
  • 排序 
Step 2 : 校正基準
  • 定義最小的動物 
  • 插入歷史評估參考 
Step 3 : 評量程度
  • Planning Poker 


遊戲規則 :
  • 一次一個人說話
  • 一次一個動作
  • 輪流

其實過程中花最多時間的是排序
這次大家在爭論的地方在於
石虎是極為珍貴重要但是處理不複雜
換言之是 Business Value高 但是Effort相對沒這麼高
兇猛動物雖然兇猛 處理的Effort高 但由於Business Value低於石虎 所以排石虎前面

不管怎麼排 一但完成排序
後面評估點數的速度就快多了!!!

這是最後的結果:




黑熊由於會自己洗澡 所以Member覺得他是最簡單的Story
而石虎由於太珍貴了 需要特別地呵護 所以給予100點

儘管結果跟PO想得不太一樣
PO覺得:
石虎有這麼困難嗎???

Member回一句 :
我們才是做事的人啊 !!!


超霸氣的啊 完全無法回嘴XD
不過下一句 PO 應該要問的是
那 石虎可以再細分Story嗎?


不管如何 這就是團隊的一個共識
先GO下去再說吧

2016-09-18

解決 為什麼無法在VS Code上 Debug

前一陣子我碰到一個Issue
我的Visual Studio Code 突然無法debug了

Error Message 如下
ERROR: CLRDBG exited unexpectedly with exit code 133 (0x85).


Google了一下 應該是我後來更新.NET Core版本之後 VSCode裡面的設定沒有跟著換
可以看一下 我電腦目前有兩個版本


project.json 仍是指到舊版本的RC2


所以手動更改Version成正確的版本即可


參考來源 : https://github.com/OmniSharp/omnisharp-vscode/issues/541

2016-09-04

受邀的TDD Workshop - Coding Dojo


今年其實我比較少接活動 但這次受到老朋友的邀請
受邀去他們部門辦一場TDD的Workshop
這是個不錯的機會能夠將這些觀念播種在公司同仁身上
於是我就準備了約4小時的課程
開場我先田野調查一下 大家開發上碰到的問題



上半場是做一些基本的Unit Test介紹
對於比較進階的打破Dependency的部分也僅僅只有點到為止

但是我發現 大家對於這塊的問題真的很感興趣

下半場則是進入今天的主題 Coding Dojo
像往常一樣讓大家試試 略有陷阱的網球計分題
讓大家體驗一下 TDD的開發模式


或許是大家都是有經驗的工程師吧
這場Coding Dojo的模式跟過去幾場比較起來比較不熱絡
反倒是問了很多實務上的問題
以下紀錄一下幾個大家提出的問題

Q1 : Stub , Mock 與 Fake的差別 ?
A1 : Stub是模擬阻礙讓測試繼續進行的石頭
        Mock比較間接 是驗證模擬對象是否預期 (你可以想成有一個函數是呼叫寄信的功能 但是我們無法驗證信到底有沒有寄到別人信箱 但是我們能有間接的方式得知到底有沒有呼叫到這個寄信函數)
        Fake是指比較接近原生物件的取代物 我會覺得也有點像Stub 但是他的對象是原生的Library. 例如 .NET Framework的物件


Q2 : 寫Unit Test 開發速度會變慢 ?
A2 : 以我自己而言 開發速度的確會稍微慢一點 有些人說需要兩倍的時間 不過我倒覺得寫UT跟一再地用手測的時間可能不會差太多 但是可以省下後面很多整合, 解Bug的時間 以及Code的品質也會比較好
資料來源 : The Art of Unit Testing: with examples in C#

Q3 : 寫Unit Test會不會造成 QA Automation出現問題 ? (註. 負負得正)
A3 : 其實這問題蠻奇怪的 我也想不出有什麼會負負得正的案例
        不過用另一個角度想 負負得正不也代表 這東西其實是有問題的 但是automation沒抓出來? 所以寫UT的效果能夠盡量讓狀態正正得正 不是才是正確的道路嗎?

Q4 : 用TDD的方式好像都沒有先想好大架構?這樣反而寫出不好的架構
A4 : 其實我自己還是會先有個初步的規劃與設計 但是TestCase仍是從需求那邊過來一步一步地建構 透過TDD的節奏 讓我能夠很快的檢視自己原本的規劃需不需要refactoring

Q5 : 專案太多Legacy Code 很多Dependency 怎麼辦?
A5 : 我不強求一定得先寫Unit Test, 所以碰到太多Dependency的就先建立一個範圍最大的一個測試 或許是Integration Test (這部分QA很厲害) 一旦測試開始建立起來 你就有信心去refactor裡面的東西 一個一個把dependency抽出來 並建立各自的Unit Test

2016-08-05

[Design Pattern] [C#] Null Object Pattern

身為一名Developer
你一定寫過類似這樣的code

Employee em = getEmployeeByDB();            
if(em != null)  {   em.IsAvailable() }
if(em != null && em.IsAvailable()) { … }
......
if(em != null) { em.IsAvailable() } if(em != null) { em.IsAvailable() } if(em != null) { em.IsAvailable() } if(em != null) { em.IsAvailable() } ......

Employee em 是來自於 getEmployeeByDB()
我們要先確認它是不是null 接下來才呼叫它的method

所以我們每次getEmployeeByDB 之後都要判斷它是不是null

是不是很麻煩 ???
是不是很麻煩 ???
是不是很麻煩 ???

所以Null Object Pattern的存在就是為了解決這個困擾

讓我們看看原本正常的一個Case
這個故事是在描述
1. 根據ID去DB查詢 並回傳一個Employee的Instance
2. 如果查無此人 就回傳 null

來看看正常情況下 程式怎麼寫吧
em 是來自於 getEmployeeByDB(string id)
所以 em 有可能是 null
因此在使用em.IsAvailable()之前必須要先確認 em 不是 null


假設我們僅讓ID為"10001" 才當作是員工 其他人都查無此人而回傳 null


Employee裡面的實作 僅為範例


getEmployeeByDB() 原本預期會回傳兩種結果
一個是正常的Employee 另一個是null



讓我們看看 如果換成 Null Object Pattern的話 要怎麼做

一個簡單的原則 產生一個介面跟Employee一樣的Class 但是要實作當狀態是Null 或是 Failure時的回傳值 (也可能是什麼都不做)



實作步驟 :

1. 我們可以將Employee抽象出一個抽象類別 ANullableEmployee
讓Employee繼承ANullableEmployee






[註] 這裡的NullableEmployee其實就是Employee 我只是換個名字

2. 實作一個Private的Null Class, NullEmployee (同樣繼承ANullableEmployee) 這是要表示當狀態是Null的物件

    這裡值得注意的點是 要override每個抽象類別定義的方法 實作的內容必須考慮當狀態是Null時 這個method必須回傳什麼才合理

3. 在抽象類別 ANullableEmployee 中 產生一個NullEmployee的靜態變數 NULL



4. 當狀態是Null或是有誤時 回傳NullEmployee 而非null



5. Caller可以直接呼叫ANullableEmployee定義的方法 不用像之前一樣要一一檢查


如果真的還是必須要判斷是不是null
可以直接去比對
em == ANullableEmployee.NULL



Null Object Pattern 是一個簡單的實作
但是能避免每次都必須重複確認的動作
不過一個比較麻煩的點是
要去思考 要用什麼行為去代表NULL
另一方面 當抽象類別增加方法時 內部的NullEmployee也一定要複寫這個新方法喔