2013年5月12日星期日
2013年4月7日星期日
限制搜尋空間 加速設計
在2月份Barcamp中跟Steven Mak一起做了一場演講,題目是「少文件、大設計、快開發」,講述以少量文件開始計劃,並以設計技巧加速開發的心德分享。因為涉獵的範圍太廣,當初就題目的決定可真費煞思良。實踐果然是最佳的驗証法,收到不少的意見,其中有段的反應不錯,所以決定獨立成文跟大家分享。
可是細心思考,失去所有限制真的是好事嗎?
試想像突然間要你寫一篇作文,題目不限,你會寫什麼?結果是飛快把文章寫出來,還是遲遲動不了筆?
<<人月神話>>的作者Frederick. P Brooks,在他的新書<<設計的設計>>中提到:
限制並非創意的制肘、相反詞,好的限制反而可以激發出創意,問題是一些誤解、過時甚至矛盾的限制,例如下圖……
有些人明確地認知到,有些人潛意識地知道,完全的自由並不存在,沒有說明限制不代表沒有限制,通常在交付時才知道。故總是恐懼著做出少於隱藏限制的工作,又害怕做出多於要求的事浪費氣力,結果精力都消耗在摸索那條不可視的界線。
所以一份清楚的需求可以幫助導論出明確的限制,但不幸的是需求不清下開發已經變成了業內的常態,雖然不支持卻只能照著辦。
但最少能快速地做到第一個版本,投資者願意付錢,又能發佈出去令士氣得以維持,正付合MVP的精神;總好過因為不肯定是否需要的問題而拖長開發時間,所以Extreme Programming有所謂"You aren't gonna need it" (YAGNI)的原則,需求修改則以TDD及Refactoring應對。
有次跟某開發團隊會面,討論他們的設計,期間提出了許多試探性的問題,例如做不做得到一項不在規格內的功能?為什麼要用/不用這方法?這個問題發生時該怎麼辦?
大部份問題都是無理,甚至是愚蠢的,持續發問是為了考驗他們對自身設計的掌握,但結果工程師的回答速度越來越慢,漸漸失去自信。
這不能怪責他們,因為需求本身就處於不清淅的狀態,在無限制的設計中,搜尋(回答)的速度必然下降。
為了讓設計得到限制,我們做了一個嘗試。
就會議中提出的所有點子、Story,不論是問題、原則、想法、猜測,只要認為重要的,請寫下並歸類成以下四種狀況:
關於限制
限制總是令人討厭,有時會聽到說要是當初沒有這個限制就能好了~事情一定更美滿之類的說辭。可是細心思考,失去所有限制真的是好事嗎?
試想像突然間要你寫一篇作文,題目不限,你會寫什麼?結果是飛快把文章寫出來,還是遲遲動不了筆?
<<人月神話>>的作者Frederick. P Brooks,在他的新書<<設計的設計>>中提到:
「限制或許是負擔,但也可能是好事。限制可以縮減設計師的搜尋空間,有所限制,比較容易聚焦並加速設計。
……
讀國中的時候,我們很多人都不喜歡「自訂題目的作文」,我們發現有些事是真的;把限制統統拿掉,會使「設計」作文的工作更加困難,而不是更簡單。
……
人為限制對設計工作來說,好處是可自由放寛限制,理想情況下,它可以把設計師推向設計空間中未經探索的角落,從而激發出創意。」
限制並非創意的制肘、相反詞,好的限制反而可以激發出創意,問題是一些誤解、過時甚至矛盾的限制,例如下圖……
要平?要好?又要快?去你的。
需求不清
沒有限制的作文令人猶疑不決;需求不清的軟件開發則舉步為艱,二者的情況其實很相似。有些人明確地認知到,有些人潛意識地知道,完全的自由並不存在,沒有說明限制不代表沒有限制,通常在交付時才知道。故總是恐懼著做出少於隱藏限制的工作,又害怕做出多於要求的事浪費氣力,結果精力都消耗在摸索那條不可視的界線。
所以一份清楚的需求可以幫助導論出明確的限制,但不幸的是需求不清下開發已經變成了業內的常態,雖然不支持卻只能照著辦。
設計不足的困境
常見於菜鳥或技能狹窄的團隊,以不變的舊方法挑戰新問題,缺乏對應問題的設計,又因解決方案的涵蓋範圍不足,結果問題多多最終難尾收場。這種團隊的常見特質是把High Risk的東西都放到最後。
過度設計的抓狂
另一種極端是過度設計,為了應付不清淅、未知的需求多想多設計不是壞事,但往往會無止盡地思考、搜尋可能性,不自覺地做出過於複雜的架構,拉長了開發時間,而更糟的是有可能做出超出能力的設計,直接出局。有點相當之有趣,就是設計不足的團隊往往比過度設計的團隊成功,因為前者最少能做出讓客戶收貨的第一個版本,雖然會因為需求修改、又或者結構太爛導至technical debt的債台高築,令開發的時間及成本不斷上昇。
但最少能快速地做到第一個版本,投資者願意付錢,又能發佈出去令士氣得以維持,正付合MVP的精神;總好過因為不肯定是否需要的問題而拖長開發時間,所以Extreme Programming有所謂"You aren't gonna need it" (YAGNI)的原則,需求修改則以TDD及Refactoring應對。
明確的時限是一種避免過度設計的限制
把想法歸成四類的分析法
有次跟某開發團隊會面,討論他們的設計,期間提出了許多試探性的問題,例如做不做得到一項不在規格內的功能?為什麼要用/不用這方法?這個問題發生時該怎麼辦?
大部份問題都是無理,甚至是愚蠢的,持續發問是為了考驗他們對自身設計的掌握,但結果工程師的回答速度越來越慢,漸漸失去自信。
這不能怪責他們,因為需求本身就處於不清淅的狀態,在無限制的設計中,搜尋(回答)的速度必然下降。
為了讓設計得到限制,我們做了一個嘗試。
就會議中提出的所有點子、Story,不論是問題、原則、想法、猜測,只要認為重要的,請寫下並歸類成以下四種狀況:
Requirement
明確地由客戶、老闆提出的需求,那是一種proven fact,無用質疑的Story都歸類在這裹。
在那次會議中可以被歸類為Requirement的想法遠比其他種類少,正是問題的所在。
Constraint
在項目管理中,Constraint指應被檢查、限制、禁止的資源及要避免的行為,同時又包括為此而採取的行動,用途是為專案所覆蓋的範圍定出明確的界線。你可以理解為完成需求而應該及不應該做的事。
Assumption
也可以稱之為Educated Guess,沒有實質的証據支持,但憑籍經驗進行猜度的各種想法。
Uncertainty
專案中的大敵,混沌的根源,理應盡早排除,但若因此過份賣力,卻會陷入過度設計的地獄。最糟的其實不是項目存在不確定、不清淅的地方,而是自己都不知道不清楚什麼,所以把Uncertainty記錄下來是有幫助整理思考的作用。
參考
若Requirement及Uncertainty處於二個極端,那麼Constraint及Assumption就是彌補二者之間的空缺,在進行軟件分析及設計時會在腦中跑出許多的點子,對這些點子過早進行批判是無益的,一來在大藍圖清淅前欠缺足夠理據下決定,二來為每個點子進行深度分析是很費時的,需要的僅是記錄及歸類。
這個歸類是很簡單的,建議可以先自行準備,然後拿出來給團隊一起研究,他們可以幫助確認想法的正確性,例如把不對的Assumption拿掉、跟客戶老闆談Uncertainly,最後變成Requirement或者Constraint等等。
故此這個分析表的內容會隨著時間而改變,理應越來越準確,在這個前提下第一版與最後版本必定有很大的出入,所以起草人不妨「大膽假設」,而非慢慢分析,寧可快點拿出起討論,反正有錯是正常的。
並非所有編程師都有規劃的能力,按部就班編程還可,規劃整個軟件卻無能為力或者費時日久,這與經驗有關,也與思考方法有關,試想像同時把數十至數百項要求同時放進腦部思考有多困難?
能同時處理、思考的數目多寡主要由天資及思維決定,不過可以用方法補救,就是利用之前寫下的分析列表,以檢核表法(Checklist Method)方式輔助思考。
在未有一個大藍圖之前,先由Requirement著手,就每個單獨的要求做一個設計:
註:如果之前已經有重覆的設計,可以考慮修改而非做一個新設計
為一個單獨的需求做的設計可以很快很簡單,但驗証卻要難得多,會無止盡地思考擔心是否足夠呢?
這時候就該把之前的分析成果拿出來用。
首先把剛完成的設計跟過往的設計比較:
然後跟分析結論再做比較:
對於經驗豐富的架構師來說,大概用途不大,因為他們已經有自己一套的分析及設計論,最大的作用是用來培育仍不得要領的新手,在有限制的時間內讓他們累積設計經驗.
事實上當我們完成了以上的分析後,工程師們回答問題的速度明顯地提昇了許多,另外發現到設計出現問題的原因多數在於Assumption出錯或Constraints不足,基本上只要協助澄清這些需求及分析結果,他們就能自行修正設計。菜鳥的話則加多把勁吧。
這方法其實是把分析及設計放在一起進行,在設計完成時分析的內容或會因此改變,這跟傳統的SDLC的先分析再設計有一定的分別,但若果說這其實更接近Winston Royce(提出Waterfall model的人)原來的想法,而且他本人就不相信Waterfall model,你會相信呢?
好比如這篇文章的主旨「利用限制加速」一樣,有時候有些固有的觀念並不一定通用,不妨用更靈活的方式去思考問題吧。這是一個初步提出的想法,歡迎大家一起討論。
若Requirement及Uncertainty處於二個極端,那麼Constraint及Assumption就是彌補二者之間的空缺,在進行軟件分析及設計時會在腦中跑出許多的點子,對這些點子過早進行批判是無益的,一來在大藍圖清淅前欠缺足夠理據下決定,二來為每個點子進行深度分析是很費時的,需要的僅是記錄及歸類。
完全不明白、猜不透的想法
|
Uncertainty
|
我覺得專案需要...吧...?
|
Assumption
|
我們要做或不要做個
|
Constraint
|
原來文件有寫的
|
Requirement
|
這個歸類是很簡單的,建議可以先自行準備,然後拿出來給團隊一起研究,他們可以幫助確認想法的正確性,例如把不對的Assumption拿掉、跟客戶老闆談Uncertainly,最後變成Requirement或者Constraint等等。
故此這個分析表的內容會隨著時間而改變,理應越來越準確,在這個前提下第一版與最後版本必定有很大的出入,所以起草人不妨「大膽假設」,而非慢慢分析,寧可快點拿出起討論,反正有錯是正常的。
限制搜尋空間的設計
並非所有編程師都有規劃的能力,按部就班編程還可,規劃整個軟件卻無能為力或者費時日久,這與經驗有關,也與思考方法有關,試想像同時把數十至數百項要求同時放進腦部思考有多困難?
能同時處理、思考的數目多寡主要由天資及思維決定,不過可以用方法補救,就是利用之前寫下的分析列表,以檢核表法(Checklist Method)方式輔助思考。
在未有一個大藍圖之前,先由Requirement著手,就每個單獨的要求做一個設計:
- 只針對這個要求做設計,不考慮其他。(除非你認為行有餘力)
- 內容可以是Use-case diagram、Class Diagram、Activity Diagram、Sequence Diagram、Deployment Diagram、Collobration Diagram,建議採用圖像化方式,但Pseudo Code及point form也可
- 如果做的是Class Diagram,不用把需求外的Class列入,比起一張overall的Class diagram,針對use-case所繪的class diagram更容易令人理解.
- 建議手繪,因為快,易加入注解,在設計成形後才轉用數碼方法
註:如果之前已經有重覆的設計,可以考慮修改而非做一個新設計
檢核表法驗証
這時候就該把之前的分析成果拿出來用。
首先把剛完成的設計跟過往的設計比較:
- 有衝突的地方嗎? => 有則一起修改,尋求一致性
- 有重覆的地方嗎? => 抽出來變成模組
然後跟分析結論再做比較:
- 有未完成的條件嗎?
- 再設計 or
- 列入Uncertainty (其實可能是不需要的做的,先記下來再討論吧!)
- 有分析文件中沒有的功能嗎?
- 再設計、刪除 or
- 列入Assumption (憑我的經驗推斷,這功能是需要的)
結論
以上嘗試提出的是一種系統性的分析及設計方法,檢核表法的作用是限制搜尋的空間,放棄無止盡地去思考,而是與過去的設計及分析結果逐一對比,若沒有修改就代表初部設計完成,定出一個明確的完成條件.對於經驗豐富的架構師來說,大概用途不大,因為他們已經有自己一套的分析及設計論,最大的作用是用來培育仍不得要領的新手,在有限制的時間內讓他們累積設計經驗.
事實上當我們完成了以上的分析後,工程師們回答問題的速度明顯地提昇了許多,另外發現到設計出現問題的原因多數在於Assumption出錯或Constraints不足,基本上只要協助澄清這些需求及分析結果,他們就能自行修正設計。菜鳥的話則加多把勁吧。
這方法其實是把分析及設計放在一起進行,在設計完成時分析的內容或會因此改變,這跟傳統的SDLC的先分析再設計有一定的分別,但若果說這其實更接近Winston Royce(提出Waterfall model的人)原來的想法,而且他本人就不相信Waterfall model,你會相信呢?
好比如這篇文章的主旨「利用限制加速」一樣,有時候有些固有的觀念並不一定通用,不妨用更靈活的方式去思考問題吧。這是一個初步提出的想法,歡迎大家一起討論。
Labels:
Agile,
Software Engineering
2012年11月10日星期六
自動化部署本機網絡測試環境
雖然我並非一位專職的網絡應用開發者,間中都要寫一點網絡應用,又或者會動手試檢不同技術的利與弊,基於很討厭在自己的Ubuntu做代碼安裝以及改動太多設定,所以通常都會在VM裹進行。
完成後都會寫一篇筆記,經驗告訢我,日後再依這篇筆記執行的成功率遠低於50%,可能有遺漏,可能軟件有修改,又或者要求根本不同了,幸好這總比重新RTFM快許多。
為了減省筆記上的錯漏,一直都想把文字script化,概可說明步驟,也可以日後依樣執行。可是若沒有好的framework配合,弄出來的script只會更加難懂…… 其實我想要的script跟自動化部署(auto deployment)系統很相似,大可直接拿來用。
花了點時間,利用ubuntu-vm-builder,fabric及puppet總算做到了這個要求。現在可以把建立測試環境及測試的程式全都放在VCS裹管理,只需要把幾個指令就可以把程式抄去VM後執行。
例子 - 建立一台VM執行Nodeload(node.js)的測試程式
指令
測試的環境是12.04,12.10相信也沒有問題,若然是11.10則要調整建立VM的參數,基於12.04是LTS版本,所以建議使用。
在接下來的例子中,會利用Nodeload建立一台Node.js的測試伺服器,即使上面的指令沒有安裝node.js也不用補回,因為將會執行的是VM而不是host/桌面機。
Puppet採用Agent/Master架構,複數Agent自動向Master取得新的設定,這是一種叫做pull機制。
而Fabric則是採取相反的Push機制,由本機把設定通過ssh推至複數的伺服器上。
單純就自動化部署系統這一範疇來說,Puppet發展迅速,不過Pull的機制對開發人員來說卻有所不便,因為要先設定多一台Master變相令建立測試環境的過程變得複雜,Push的形式比較簡單,所以我採用了混合的做法:
第一步是建立fabfile.py,內容如下:
上例中有一個叫做create()的函數,可以通過指令`fab create`執行,
完成後可以用指令`sudo virsh start nodejs`來起動VM。
像Fabric般使用script方式來進行設定是相當之直觀的方法,Puppet的描述語言則相對迂迴,但以configration management的角度看,追蹤修改比較容易。另外統一的資源/模型描述方法,使不同軟件之間的設定的差異化減少,有便於管理。(詳情)
要進行這部驟的指令是`fab setup`,代碼:
Fabric在這裏的作用只是把.pp檔拷到VM後執行`puppet apply`而已。
要是對這種測試方法有興趣,又想尋找更多的use-case,可以參考 Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation
完成後都會寫一篇筆記,經驗告訢我,日後再依這篇筆記執行的成功率遠低於50%,可能有遺漏,可能軟件有修改,又或者要求根本不同了,幸好這總比重新RTFM快許多。
為了減省筆記上的錯漏,一直都想把文字script化,概可說明步驟,也可以日後依樣執行。可是若沒有好的framework配合,弄出來的script只會更加難懂…… 其實我想要的script跟自動化部署(auto deployment)系統很相似,大可直接拿來用。
花了點時間,利用ubuntu-vm-builder,fabric及puppet總算做到了這個要求。現在可以把建立測試環境及測試的程式全都放在VCS裹管理,只需要把幾個指令就可以把程式抄去VM後執行。
例子 - 建立一台VM執行Nodeload(node.js)的測試程式
指令
- fab create #建立VM
- fab setup #設定VM,例如下載node.js及其node.js模組
- fab deploy #把測試程式拷到VM執行
- fab view #開啟Browser查看結果
準備工作
首先你要有一台Ubuntu,然後安裝以下軟件sudo apt-get fabric ubuntu-vm-builder #你不一定需要裝Puppet,也不需要安裝Node.js,請看下文。如果沒有建立自己的ssh key,請先用ssh-keygen建立。
測試的環境是12.04,12.10相信也沒有問題,若然是11.10則要調整建立VM的參數,基於12.04是LTS版本,所以建議使用。
在接下來的例子中,會利用Nodeload建立一台Node.js的測試伺服器,即使上面的指令沒有安裝node.js也不用補回,因為將會執行的是VM而不是host/桌面機。
Fabric及Puppet的簡介
這二個軟件都可以歸類為自動化部署系統,例如可以把設定及執行檔安裝至複數的伺服器上,但二者之間的運作原理卻非常之不同。Puppet採用Agent/Master架構,複數Agent自動向Master取得新的設定,這是一種叫做pull機制。
而Fabric則是採取相反的Push機制,由本機把設定通過ssh推至複數的伺服器上。
單純就自動化部署系統這一範疇來說,Puppet發展迅速,不過Pull的機制對開發人員來說卻有所不便,因為要先設定多一台Master變相令建立測試環境的過程變得複雜,Push的形式比較簡單,所以我採用了混合的做法:
使用Fabric把設定檔推至VM,再執行Puppet把設定更新。
建立VM
在這個例子中我不打算使用VMWare或者VirtualBox這類方案,而是使用Kernel-based Virtual Machine(KVM)配合QEMU+libvirt,介面上當然比不過前二者,不過勝在可以透過ubuntu-vm-builder輕易地建立可執行的Ubuntu影像,並自動執行初始化設定。第一步是建立fabfile.py,內容如下:
from __future__ import with_statement from fabric.api import local, settings, abort, run, cd , put from fabric.contrib.console import confirm from fabric.api import env from fabric.context_managers import prefix machine = "nodejs" # Name of the testing machine def create(): # Create a testing machine # Remarks: You should not permit root logins via SSH in a networking # environment, because this is a big and unnecessary security risk. # # It is enabled here for simplify the tasks required to build # a testing machine. Never do it in production and even on # a machine within your office network. dist = "precise" mem = 128 packages = ["openssh-server" , "puppet" , "nodejs" ,"npm"] package = " ".join([ "--addpkg %s" % x for x in packages]); options = ["--libvirt qemu:///system", # Add to libvirt "--lang=C", "--ssh-key ~/.ssh/id_dsa.pub", "-d /var/lib/libvirt/images/%s" % machine, "--hostname %s" % machine, "--mem=%s" % mem, "--name=%s" % machine ] option = " ".join(options); command = "sudo ubuntu-vm-builder kvm %s qemu:///system %s %s" % (dist , package,option) local(command)
上例中有一個叫做create()的函數,可以通過指令`fab create`執行,
完成後可以用指令`sudo virsh start nodejs`來起動VM。
註1:我把自己的SSH key放入VM的root中,使得可以經ssh登入root而不需要密碼,對於測試環境來說是相當之方便,但千萬不能在網絡環境中卻是採用,那是非常之壞的習慣。
註2:Ubuntu-vm-builder大概已經不會再有大的發展,之後的開發核心看來是lxc/juju,之所以沒有採用後者是因為還未學會使用。另外你喜歡使用VirtualBox的話,則可以選擇Vagrant。
執行Puppet
開動VM後下一步是進行系統設定,這部驟由Puppet進行。在VCS中有二個.pp檔,那是Puppet的設定檔,用以宣告資源,當中記錄了要安裝的軟件,但因為要使用到apt、gems、npm三種不同的套件管理程式,所以並不能用幾行描述完成。像Fabric般使用script方式來進行設定是相當之直觀的方法,Puppet的描述語言則相對迂迴,但以configration management的角度看,追蹤修改比較容易。另外統一的資源/模型描述方法,使不同軟件之間的設定的差異化減少,有便於管理。(詳情)
要進行這部驟的指令是`fab setup`,代碼:
def setup(): # Setup the testing machine using puppet put("setup*.pp" ,"/tmp") run("puppet apply /tmp/setup-phase1.pp") run("puppet apply /tmp/setup-phase2.pp")
Fabric在這裏的作用只是把.pp檔拷到VM後執行`puppet apply`而已。
進行測試
最後一步是把測試程式放入VM執行,指令是`fab deploy`,然後在另一個Terminal中輸入`fab view`就會自動打開browser查看實際結果.$ fab deploy [192.168.122.118] Executing task 'deploy' [192.168.122.118] put: ../src/nodeload-server.js -> /tmp/nodeload-server.js [192.168.122.118] run: killall -9 node;echo [192.168.122.118] out: node: no process found [192.168.122.118] run: node /tmp/nodeload-server.js [192.168.122.118] out: Started test server. [192.168.122.118] out: Started HTTP server on localhost:8000.
執行結果
總結
如果只為一次測試寫上以上的程式,老實說我也覺得小題大造,但如果考慮到日後可以重覆使用,這一切就會變得物超所值。這刻只有建立node.js的.pp,日後可以加入MongoDB、Redis、MySQL,Nginx、Memcache、ZooKeeper..... 你想怎樣配搭都可以,當你不需要時只需把VM關掉,會佔用的僅是硬碟空間。要是對這種測試方法有興趣,又想尋找更多的use-case,可以參考 Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation
Labels:
Software Engineering
2012年6月19日星期二
故事式規劃設計
Agile/Scrum的開發流程中有許多傳統方法沒有的新概念,例如採用Story Point而非Ideal day/man hour去計算工作量;用Burndown Chart取代Gantt Chart等等。
比起使用Issue Tracker來管理工作,Agile/Scrum更傾向於使用Task Board,那是一面貼著各種工作的牆,猶如RPG世界中的冒險工會中擺放任務的告示板,不過更有系統也不至於混亂。
User Story是Agile的常用語,用一二句簡單的說話描述要求、工作以至其他訊息,通常會以手寫的方式寫在便條紙又或者資料卡上。
Task Board的作用就是放置這些User Story,通常會再以TODO、In Progress、Verify及Done等不同階段分類。每天會通過一個10~15分鐘的小型會議重新調整。
對於習慣使用Issue tracker的我而言,最初接觸這個概念只感到不可思義,為什麼有著高科技的軟件不用而走回紙本啊!?
實際經歷過後找到了答案。
剛開始引入Agile/Scrum時覺得便條紙不太可靠,所以選擇了用資料卡。很快就發現這些資料卡除了在Task board外還有很多其他的用途。
延伸應用
在Agile的定義中,User Story是指用簡短文字描述的工作要求,不過我覺得可以把Story的定義再擴闊,User Story也可以是限制、假設、原則、設計提案、設計模式、問題、疑惑、風險、不確定性,所有經過討論產生的內容,只要內容夠精練也可以是一個故事。
至於寫在資料卡上,則是一項減省文件工作量的方法,像是經歷二中提到的會議,首先可以讓各人淪流書寫,最好是提出者自己寫下,犯不著要犧牲任何一位工程師去當秘書做會議記錄,資料卡(現在可以叫做故事卡)概是記錄、也是設計的一環,只要存放在所有工程師們都能取閱的地方,概可以保持執行的一致性,也可以避免文件地獄。
這也可以算是一種協同寫作。
至於開會地獄呢,這得看主持人的功能及各人會否就個別故事展開過長的討論,關於這點我另寫一篇文章再談。
總結
資料卡有不同的大少,我喜歡購買5" x 3"這種大少的,因為書寫空間有限,所以一張卡最好只放單一的命題,並用簡短卻又切入核心的文字及圖案補充。
這種方法在資料內容上有很多的限制,但限制也不一定是件壞事,套用《The Design of Design》一書中提到的說法,限制或許是負擔,但也可能是好事,有所限制比較容易聚焦並加速設計。
用精練文字描述故事也是一種設計的磨練。
雖然這篇文章的標題是"故事式規劃設計" ,但其實真正想介紹的卻是資料卡的運用 ;)
在閣下的團隊正式引入Agile / Scrum時,不妨先試一試用資料卡書寫故事,像是在「經歷二」中的那種會議中使用,把分析出來的內容故事化,你會發覺記錄的效率會大大的提昇,而且之後還會發現更多有趣的延伸應用方法。
比起使用Issue Tracker來管理工作,Agile/Scrum更傾向於使用Task Board,那是一面貼著各種工作的牆,猶如RPG世界中的冒險工會中擺放任務的告示板,不過更有系統也不至於混亂。
各類型的Task Board
User Story是Agile的常用語,用一二句簡單的說話描述要求、工作以至其他訊息,通常會以手寫的方式寫在便條紙又或者資料卡上。
左 - 資料卡 右 - 便條紙
Task Board的作用就是放置這些User Story,通常會再以TODO、In Progress、Verify及Done等不同階段分類。每天會通過一個10~15分鐘的小型會議重新調整。
對於習慣使用Issue tracker的我而言,最初接觸這個概念只感到不可思義,為什麼有著高科技的軟件不用而走回紙本啊!?
實際經歷過後找到了答案。
剛開始引入Agile/Scrum時覺得便條紙不太可靠,所以選擇了用資料卡。很快就發現這些資料卡除了在Task board外還有很多其他的用途。
經歷一) 快速決定功能的重要性
話說有一個專案,客戶要求的功能是沒有辦法在指定的時間內完成,這點客戶都明白。
唯有先把最有價值的功能弄出來,次要的功能則在死線後加回。
把需求列表印了出來,接著大家七嘴八舌討論,意見太多、缺乏焦點、就是沒有辧法決定出優先序。
最後我把心一橫,把所有功能寫在資料卡上,在客戶面前攤開,然後玩起拼圖遊戲。
最重要的工作放在最頂點,平放代表拿不定主意,
這些平放的"故事"交由開發團隊決定優先序
這些平放的"故事"交由開發團隊決定優先序
最初的排列是隨機的,可是當各項工作以視覺化的形式呈現了出來後,思考會變得輕鬆,而且各人直接動手更改排序令敏捷度大增,結果很快就敲定了決議。經歷二) 快速需求分析及設計雛型
其實這過程還不知不覺地把問題本質改變。
最初是的要求是「請為每個工作定優先序」,這等於請你去為工作的價值估值。
當然每個人都有能力做估值這工作,可是該怎樣把各人的估值整合?平均數法固然公平,可是不一定代表能做出好的設計,基於大家的著眼點並不一致,平均數法可能得出違背最多人想法的決定。
可是通過這方法,問題卻變成 - 「請問桌上面的排序有你不滿意的地方嗎?」
現在追求的不再是優先序絕對值,而是各功能的比較值,其實各人根本沒有興趣知道功能A的優先序有多高於功能B,只要知道功能A優於功能B便可。
如果沒有反對則默認通過,反對則直接動手改變次序,當然仍然需要溝通,但反覆排了幾次,爭論點就會減少,代表大家重視的工作及衝突得以解決,漸漸一個比較接近各人心中理想的答案就會以視覺化的方式呈現在眼前。
要求文件確實地收到了,不過團隊是初成立的,經驗豐富者堪少,這時候採取的方法有二,一是單獨派發任務後自動執行,二是透過共同協商解決問題。
前者自生自滅,在整合時便因為撞車而屍橫遍地;後者一不小心就會變成開會或文件地獄。
結果採用後者,一起討論需求文件,每次在文件中找出一項工作、需求、限制、疑問、資源、對應的設計策略、或者找出了潛在的要求時,都會立即寫在資料卡上。
首先把寫上疑問的資料卡收集,依此跟客戶澄清。之後把工作的卡片卡抽出,經過Planning Poker定下Story Point把所有卡片放在桌上,然後大家就再玩起拼圖遊戲,最後變成工作的計劃。
一份需求文件寫成40多張故事卡已經算少了,看似辛苦卻是先苦後甜的一項作業,首先把不確定性排除不小,而且各人對計劃都能有比較一致性的認識。
如果有經驗深厚者在場,也可以順道做出一些設計的雛型規劃,給予其他人一個明確的方向。
跟著就把工作貼在Task Board上好了,把這些資料重新輸入Issue Tracker可是一件相當之累人的工作!Defeat及Bug等工作的記錄才出動Redmine吧。
已經習慣了使用Planning Poker來計算工作難度,再推論出實際所需的時間。
Planning Poker也可以好萌 (以上二款均為Odd-e出品)
延伸應用
在Agile的定義中,User Story是指用簡短文字描述的工作要求,不過我覺得可以把Story的定義再擴闊,User Story也可以是限制、假設、原則、設計提案、設計模式、問題、疑惑、風險、不確定性,所有經過討論產生的內容,只要內容夠精練也可以是一個故事。
至於寫在資料卡上,則是一項減省文件工作量的方法,像是經歷二中提到的會議,首先可以讓各人淪流書寫,最好是提出者自己寫下,犯不著要犧牲任何一位工程師去當秘書做會議記錄,資料卡(現在可以叫做故事卡)概是記錄、也是設計的一環,只要存放在所有工程師們都能取閱的地方,概可以保持執行的一致性,也可以避免文件地獄。
這也可以算是一種協同寫作。
至於開會地獄呢,這得看主持人的功能及各人會否就個別故事展開過長的討論,關於這點我另寫一篇文章再談。
數個月就可以花掉那麼"厚"的資料卡啊
總結
資料卡有不同的大少,我喜歡購買5" x 3"這種大少的,因為書寫空間有限,所以一張卡最好只放單一的命題,並用簡短卻又切入核心的文字及圖案補充。
這種方法在資料內容上有很多的限制,但限制也不一定是件壞事,套用《The Design of Design》
用精練文字描述故事也是一種設計的磨練。
雖然這篇文章的標題是"故事式規劃設計" ,但其實真正想介紹的卻是資料卡的運用 ;)
在閣下的團隊正式引入Agile / Scrum時,不妨先試一試用資料卡書寫故事,像是在「經歷二」中的那種會議中使用,把分析出來的內容故事化,你會發覺記錄的效率會大大的提昇,而且之後還會發現更多有趣的延伸應用方法。
Labels:
Agile,
Software Engineering
2012年2月21日星期二
需求分析 - 魔鬼都藏在細節裡
早前看到了這個故事(來源):
某日,老師在課堂上想考考學生們的智商,就問一個男孩: 「樹上有十隻鳥,開槍打死一隻,還剩幾隻?」
男孩反問:「是無聲手槍,還是其他沒有聲音的槍麼?」
「不是.」
「槍聲有多大?」
「80~100分貝.」
「那就是說會震的耳朵疼?」
「是.」
「在這個城市裡打鳥犯不犯法?」
『不犯.」
「您確定那隻鳥真的被打死啦?」
「確定.」老師已經不耐煩了,」拜託,你告訴我還剩幾隻就行了,OK?」
「OK.鳥裡有沒有聾子?」
「沒有.」
「有沒有鳥智力有問題,呆傻到聽到槍響不知道飛的?」
「沒有,智商都在200以上!」
「有沒有關在籠子裡的?」
「沒有.」
「邊上還有沒有其他的樹,樹上還有沒有其他鳥?」
「沒有.」 「方圓十里呢?」 「就這麼一棵樹!」
「有沒有殘疾或餓的飛不動的鳥?」
「沒有,都身體倍棒.」
「算不算懷孕肚子裡的小鳥?」
「都是公的.」
「都不可能懷孕?」
「………,決不可能.」
「打鳥的人眼裡有沒有花?保證是十隻?」
「沒有花,就十隻.」 老師腦門上的汗已經流下來了,
下課鈴響起,但男孩仍繼續問:「有沒有傻的不怕死的?」
「都怕死.」
「有沒有因為情侶被打中,自己留下來的?」
「笨蛋,之前不是說都是公的嘛!」
「同志可不可以啊!」
「………….,性取向都很正常!」
「會不會一槍打死兩隻?」
「不會.」
「一槍打死三隻呢?」
「不會.」
「四隻呢?」
「更不會!」
「五隻呢?」
「絕對不會!!!」
「那六隻總有可能吧?」
「除非你他媽的是豬生的才有可能!一槍只能打死一隻!」
「…好吧,那麼所有的鳥都可以自由活動麼?」
「完全可以.」
「它們受到驚嚇起飛時會不會驚慌失措而互相撞上?」
「不會,每隻鳥都裝有衛星導航系統,而且可以自動飛行.」
「嗯,如果您的回答沒有騙人,」學生滿懷信心的回答,「打死的鳥要是掛在樹上沒掉下來,那麼就剩一隻,如果掉下來,就一隻不剩.」
老師推推眼鏡,強忍著要昏倒的感覺,顫抖地說道:「你可以去當程序員了……」
=== 故事完 ===
這是個極誇張的故事,不過卻道出了程式師在分析需求時的應有心態。
提出需求的人有他自己的專業,與程式師的專業很有可能走在一條沒有交點的平衡線上,但程式師的專業之一就是把這些需求變成技術的設計要求;這是一個翻譯的過程,好比如作為火星人的程式師把金星語翻譯給其他同類聽,還要為此作出各種配置。
在這時要記著一點:「魔鬼都藏在細節裡」
需求就像一道陷阱式的IQ題,解題的重點不是自己的智識,而是補捉出題者的用神,只有理解出題者的思路才會有正確的答案。
最常見的陷阱是需求的標題與細節不符,又或者在需求A中沒有的細節,卻在需求B中出現。
不是說提出需求的人在騙你,而是因為專業的不同,對方不一定了解什麼資訊是程式師最是需要,對方可能覺得要求完美,但在技術的角度卻充滿破綻,一不留神就會墮入誤解的魔鬼陷阱。
最後在交貨時,對方質疑與要求不符,他們想要的是一道滿漢全席,但你卻提供了西洋大餐,那你會怎樣做?
軟體工程是一件很奇妙的事,法例是不可能以立法原義去做裁決(所以香港也很奇怪),但當軟件交貨時卻可能會有這種聲音 - 「我才不是想要這種軟件!」
這不是傲嬌的台詞,你不會萌得起來,只會頭痛。(除非是這種客戶)
應付這種客人當然辛苦,但同時請捫心自問,技術人員有沒有為需求而與客戶溝通好呢?有沒有先找出細節中的魔鬼 - 可以引起誤會的地方?
用心跟客戶談需求,分析需求後,指出有些對方未有留意的細節,再因勢利道再提出建議的做法,這不但能減少日後的爭論,同時能建立自己的專業形像,更容易獲得對方的尊重,可以讓合作更容易進行。
最佳的做法是學故事中那學生,就像一位名偵探般懷疑一切的可能性,可是千萬別宣之於口,這會讓人覺得你相當之白目。而且記著你的身份不真的是偵探,別要去盤問客戶,而要以輕鬆的語氣試探,慢慢切入問題的中心 - 你認為最有可能因為需求理解錯誤而出錯的地方。
如果遇著對方有點迷糊時,不妨花點時間去解釋,雖然對方往往想知的僅是解決方案,不過這點解釋的時間讓對方感到被尊重而得到對方的信任。直至真的沒法構通才出最後的方案 - 在合約中列明不包括的事務,當然必需要跟對方解理一次。
當然像是採用像Agile/Scrum般經常快速交付的做法也是一種解決方法,不過那是另一種技巧了。
相關閱讀
=== 故事 ===
某日,老師在課堂上想考考學生們的智商,就問一個男孩: 「樹上有十隻鳥,開槍打死一隻,還剩幾隻?」
男孩反問:「是無聲手槍,還是其他沒有聲音的槍麼?」
「不是.」
「槍聲有多大?」
「80~100分貝.」
「那就是說會震的耳朵疼?」
「是.」
「在這個城市裡打鳥犯不犯法?」
『不犯.」
「您確定那隻鳥真的被打死啦?」
「確定.」老師已經不耐煩了,」拜託,你告訴我還剩幾隻就行了,OK?」
「OK.鳥裡有沒有聾子?」
「沒有.」
「有沒有鳥智力有問題,呆傻到聽到槍響不知道飛的?」
「沒有,智商都在200以上!」
「有沒有關在籠子裡的?」
「沒有.」
「邊上還有沒有其他的樹,樹上還有沒有其他鳥?」
「沒有.」 「方圓十里呢?」 「就這麼一棵樹!」
「有沒有殘疾或餓的飛不動的鳥?」
「沒有,都身體倍棒.」
「算不算懷孕肚子裡的小鳥?」
「都是公的.」
「都不可能懷孕?」
「………,決不可能.」
「打鳥的人眼裡有沒有花?保證是十隻?」
「沒有花,就十隻.」 老師腦門上的汗已經流下來了,
下課鈴響起,但男孩仍繼續問:「有沒有傻的不怕死的?」
「都怕死.」
「有沒有因為情侶被打中,自己留下來的?」
「笨蛋,之前不是說都是公的嘛!」
「同志可不可以啊!」
「………….,性取向都很正常!」
「會不會一槍打死兩隻?」
「不會.」
「一槍打死三隻呢?」
「不會.」
「四隻呢?」
「更不會!」
「五隻呢?」
「絕對不會!!!」
「那六隻總有可能吧?」
「除非你他媽的是豬生的才有可能!一槍只能打死一隻!」
「…好吧,那麼所有的鳥都可以自由活動麼?」
「完全可以.」
「它們受到驚嚇起飛時會不會驚慌失措而互相撞上?」
「不會,每隻鳥都裝有衛星導航系統,而且可以自動飛行.」
「嗯,如果您的回答沒有騙人,」學生滿懷信心的回答,「打死的鳥要是掛在樹上沒掉下來,那麼就剩一隻,如果掉下來,就一隻不剩.」
老師推推眼鏡,強忍著要昏倒的感覺,顫抖地說道:「你可以去當程序員了……」
=== 故事完 ===
這是個極誇張的故事,不過卻道出了程式師在分析需求時的應有心態。
提出需求的人有他自己的專業,與程式師的專業很有可能走在一條沒有交點的平衡線上,但程式師的專業之一就是把這些需求變成技術的設計要求;這是一個翻譯的過程,好比如作為火星人的程式師把金星語翻譯給其他同類聽,還要為此作出各種配置。
在這時要記著一點:「魔鬼都藏在細節裡」
需求就像一道陷阱式的IQ題,解題的重點不是自己的智識,而是補捉出題者的用神,只有理解出題者的思路才會有正確的答案。
最常見的陷阱是需求的標題與細節不符,又或者在需求A中沒有的細節,卻在需求B中出現。
不是說提出需求的人在騙你,而是因為專業的不同,對方不一定了解什麼資訊是程式師最是需要,對方可能覺得要求完美,但在技術的角度卻充滿破綻,一不留神就會墮入誤解的魔鬼陷阱。
最後在交貨時,對方質疑與要求不符,他們想要的是一道滿漢全席,但你卻提供了西洋大餐,那你會怎樣做?
A - 文件就是這樣寫,我不會修改的選A,大家之後不相往來;選B,很快又要再做一次。
B - 好,我改……
軟體工程是一件很奇妙的事,法例是不可能以立法原義去做裁決(所以香港也很奇怪),但當軟件交貨時卻可能會有這種聲音 - 「我才不是想要這種軟件!」
這不是傲嬌的台詞,你不會萌得起來,只會頭痛。(除非是這種客戶)
應付這種客人當然辛苦,但同時請捫心自問,技術人員有沒有為需求而與客戶溝通好呢?有沒有先找出細節中的魔鬼 - 可以引起誤會的地方?
其實只要在分析需求時把關好一點,很多問題都可以避免的。
用心跟客戶談需求,分析需求後,指出有些對方未有留意的細節,再因勢利道再提出建議的做法,這不但能減少日後的爭論,同時能建立自己的專業形像,更容易獲得對方的尊重,可以讓合作更容易進行。
最佳的做法是學故事中那學生,就像一位名偵探般懷疑一切的可能性,可是千萬別宣之於口,這會讓人覺得你相當之白目。而且記著你的身份不真的是偵探,別要去盤問客戶,而要以輕鬆的語氣試探,慢慢切入問題的中心 - 你認為最有可能因為需求理解錯誤而出錯的地方。
如果遇著對方有點迷糊時,不妨花點時間去解釋,雖然對方往往想知的僅是解決方案,不過這點解釋的時間讓對方感到被尊重而得到對方的信任。直至真的沒法構通才出最後的方案 - 在合約中列明不包括的事務,當然必需要跟對方解理一次。
當然像是採用像Agile/Scrum般經常快速交付的做法也是一種解決方法,不過那是另一種技巧了。
相關閱讀
Labels:
Software Engineering
2011年5月26日星期四
Bazaar的培訓教材
Bazaar是我最喜愛的分散式源碼管理系統,因為:
畢竟軟體開發往往不祇是一個人的事,許多時還得為其他人著想……在香港,沒有使用或仍停留在CVS的源碼管理系統的工程師比想像中更要多……,過於複雜的系統只會拖垮他們的步伐,至於我個人也不想花太多在培訓及解決其他人各種的疑難……
即使Bazaar非常之容易掌握,可是許多人的概念仍停留在中央式的源碼管理系統上,對於分散式式系統的使用方法,以及帶來的Workflow轉變不堪了解,所以一些基本的入門培訓課程還是對初學者有幫忙的。
最近正好要辦相關的培訓,為了這個活動我特意準備一份教材,題目是:
教材以Creative Commons的CC BY-NC-SA 2.0形式授權,歡迎非商業的使用,不過所謂的商業僅是指用來贊錢而已,閣下要用來培訓員工自然是無任歡迎。
內容集中在Workflow中,列出不同的workflow,以及當中會用到的Bazaar的功能。為了照顧初學者的所需,也列出了許多非常之基本的指令,希望到你們有用。
- 入門的難度要求低 - 不會一開始便有相當之嚇人的概念、名詞要懂
- 立即使用 - 只要能分享檔案就能進行團隊開發,不論你是用Samba、Windows的檔案分享,甚至是Dropbox也可以,服務器端不用安裝Bazaar便能立即開始新計劃。
- 功能強大 - 雖然在這方面總是會被拿來跟git比較,可是Bazaar所提供的功能可說是已經符合絕大部份的開發過程所需的。
- 便利的圖像介面 - 初學者容易掌握,也有為進階用戶而設的工具
- 跨平台能力優秀 - 無論是Linux、Mac及Windows都有natvie的安裝程式,而且有統一的圖像介面(Bazaar Explorer),得到的經驗可以帶去其他平台上使用
畢竟軟體開發往往不祇是一個人的事,許多時還得為其他人著想……在香港,沒有使用或仍停留在CVS的源碼管理系統的工程師比想像中更要多……,過於複雜的系統只會拖垮他們的步伐,至於我個人也不想花太多在培訓及解決其他人各種的疑難……
即使Bazaar非常之容易掌握,可是許多人的概念仍停留在中央式的源碼管理系統上,對於分散式式系統的使用方法,以及帶來的Workflow轉變不堪了解,所以一些基本的入門培訓課程還是對初學者有幫忙的。
最近正好要辦相關的培訓,為了這個活動我特意準備一份教材,題目是:
Getting Started with Bazaar , How it change your workflow
教材以Creative Commons的CC BY-NC-SA 2.0形式授權,歡迎非商業的使用,不過所謂的商業僅是指用來贊錢而已,閣下要用來培訓員工自然是無任歡迎。
內容集中在Workflow中,列出不同的workflow,以及當中會用到的Bazaar的功能。為了照顧初學者的所需,也列出了許多非常之基本的指令,希望到你們有用。
Labels:
Software Engineering,
VCS
2011年5月23日星期一
讓文件輕鬆完成 - 協同寫作
除非是一些小型或者個人的開發計劃,否則文件是不可或缺的 ﹣ 這是大部份人都認同的想法,可是實際上無數中至大型的專案都有文件殘缺不全的問題,每次要求文件往往都會發生時空扭曲,像是回到傳疑時代要靠「口耳相傳」的方式把項目故事流傳下去。
若問為何如此,大概是因為大部份人(特別是技術人員)都把撰寫文件視為厭惡性的工作吧。
故此有些公司會找專責的人員寫文件,有時會是technical writer,有時則是manager、也有機會找Marketing/sales代勞 ﹣ 因為那是客戶要求的東西,至於是否能反應實際情況.... 天知曉。
而沒有專責人員的公司.. well.. 沒有文件是很平常,有時候更會鬧出笑話。
這個故事告訢我們有些老闆是白痴的 文件有時要花費莫大的代價…
這種完全不寫、寫不出文件的人並不是十分罕見,在某些地方會經常遇到,不過主要的原因不是出於腦子有文字處理的困難,實質是為了保障自己的措施,為了讓僱主難以把他開除才故意寫不出來。
如果我是老闆會優先解僱這種員工。
雖然一般的Programmer大多討厭寫文件,但到底討厭的是寫冗長的文件、還是真的連半點文字都寫不出來呢?老實說後者實在不太可能,這可能要去看一看醫生了,所以真正討厭的是寫沉長、甚至沒人看的文件 - 筆者也怕寫這種文件
不會因此就連半點文件都不寫就是非專業所為了,最低限度如規格、時程、編譯指南、簡短的使用方法等還得由programmer撰寫。
Programmer的本職畢竟不是文字上的寫手,花費過多的時間在文件上會反而影響開發的進度,而且也會讓他們卻步。
故問題是怎樣降低花上文件上的時間而又能維持一定的質素,筆者的建議是collaborative writing(協同寫作),別要一個人把整個系統的文件寫出來,而是各人分工寫不同的部份,然後再檢閱其他有關模組的文件(這通常是由別人寫的),再提出意見、修定,互相彌補不足之處。
首先要文件寫得淺白而懂、連麻瓜都看得懂等的要求拋棄,他們想看的其實是Harry Patter,但你可不是J·K·羅琳;你是一名專業的工程師,這表現在資料的詳盡程度及內容編排上,有需要的也得提供圖片。
然後你要
把以上寫、校對的過程重複幾次,一份詳盡而又足夠讓技術人員明白的文件就會誔生。
至於是否一份讓管理層贊賞的文件……?well,別做多餘的事。記得在大學工程學院讀書時,technical writing那課特別強調文件要寫得淺白易懂、更要讓麻瓜也看得明白…………這是嚇壞programmer的原由之一吧!
真的是弄出針對一般人看的文件,不如直接請個專責的technical writer吧!
雖然時間長了一點,不過協同寫作對所有人的壓力都是最低的,可以讓programmer更樂於從事文件的寫作。
要做到協同寫作,最簡單的方法莫過於使用wiki,概可讓多人同時寫作,又有版本控制,追蹤修定也非常的簡單。
Wiki的好處:
相關閱讀
若問為何如此,大概是因為大部份人(特別是技術人員)都把撰寫文件視為厭惡性的工作吧。
故此有些公司會找專責的人員寫文件,有時會是technical writer,有時則是manager、也有機會找Marketing/sales代勞 ﹣ 因為那是客戶要求的東西,至於是否能反應實際情況.... 天知曉。
而沒有專責人員的公司.. well.. 沒有文件是很平常,有時候更會鬧出笑話。
話說在某U公司,曾經聘請了某內地高手C開發了一件硬件產品,這產品會用於某系統上,完成後則連整個系統交付了給第一位客戶,然後就離職了,他所留下的只有線路及firmware的binary,還有一份難以理解的protocol文件。
後來要把這件產品裝嵌在另一個系統上,新晉的工程師B無法理解這是什麼鬼東西,沒有說明文件,那就自己去研究這東西是做什麼的吧,理解是理解了,不過沒有規格,所以根本不知道能力的上下限在那裹,更甚至他認為這東西其實是廢物來的,只要買個Programmable Logic Controller回來就有等效的能力,而且更平宜。
及後C回巢,B立即提出要求C補回當年的文件,殊不知老闆D與C其實是很要好的朋友,這東西本來就是他們聯手想出的「偉大構思」,基於C又是一位極度厭惡寫文件的人,而又獲得老闆的特別照顧,結果D就異想天開地想出一個方法,就是由D本人開班授徒,把這「偉大的構思」教給其他工程師,再由這些工程師去補寫文件。
那天除了D以外,還有一位manager及四位工程師。
粗略以老闆50k、manager 30k及各工程師17k的人工計算,假設22個工作天,這份大概30多頁紙的文件就得花上近7千元港幣的代價(相信已經低估了這班人的人工),而且故事也沒那麼順利,因為老闆D根本就不懂.....花了一天講的都不過是他所猜度的內容,最後另一位工程師A費了很大的勁力才真的弄出了一份文件。
這個故事告訢我們
這種完全不寫、寫不出文件的人並不是十分罕見,在某些地方會經常遇到,不過主要的原因不是出於腦子有文字處理的困難,實質是為了保障自己的措施,為了讓僱主難以把他開除才故意寫不出來。
雖然一般的Programmer大多討厭寫文件,但到底討厭的是寫冗長的文件、還是真的連半點文字都寫不出來呢?老實說後者實在不太可能,這可能要去看一看醫生了,所以真正討厭的是寫沉長、甚至沒人看的文件 - 筆者也怕寫這種文件
不會因此就連半點文件都不寫就是非專業所為了,最低限度如規格、時程、編譯指南、簡短的使用方法等還得由programmer撰寫。
Programmer的本職畢竟不是文字上的寫手,花費過多的時間在文件上會反而影響開發的進度,而且也會讓他們卻步。
故問題是怎樣降低花上文件上的時間而又能維持一定的質素,筆者的建議是collaborative writing(協同寫作),別要一個人把整個系統的文件寫出來,而是各人分工寫不同的部份,然後再檢閱其他有關模組的文件(這通常是由別人寫的),再提出意見、修定,互相彌補不足之處。
首先要文件寫得淺白而懂、連麻瓜都看得懂等的要求拋棄,他們想看的其實是Harry Patter,但你可不是J·K·羅琳;你是一名專業的工程師,這表現在資料的詳盡程度及內容編排上,有需要的也得提供圖片。
然後你要
- 擔當一名有限能力的寫手,寫出自己負責的部份的文件,再拜託其他同事幫忙校對。
- 同時擔當一名副業的校對人員,查閱跟自己有關的文件並提出意見,有需要時會自行修改。
把以上寫、校對的過程重複幾次,一份詳盡而又足夠讓技術人員明白的文件就會誔生。
至於是否一份讓管理層贊賞的文件……?well,別做多餘的事。記得在大學工程學院讀書時,technical writing那課特別強調文件要寫得淺白易懂、更要讓麻瓜也看得明白…………這是嚇壞programmer的原由之一吧!
真的是弄出針對一般人看的文件,不如直接請個專責的technical writer吧!
別要求programmer當作家,他們的責任應當是提供一切需要的資訊,讓文字美化的工作需找其專責的人員舉一個例子。
在筆者任職過的某公司,要用某嵌入式平台進行開發,包括筆者在內沒有任何人有過這平台的經歷,故找了某君當前鋒摸索,那時筆者要求他把結果寫成文件,而他立即面露難色。
筆者就降低要求,只需要把打過的指令及使用的檔案例出來,文件的第一版很快就完成了。
然後筆者跟著這份文件設定環境,過程中加上適當的指示,有無法進行的步驟則要求原作者補充,花了點時間終於完成了第二版的文件,其他同事就依第二版文件進行設定,大部份都能立即上手。
後來要讓其他部們的人也跟著做,基於專業有異,第二版的文件他們有許多地方看不懂,收集了他們的疑問後弄出了第三版 - 那是連非這個專業的人都能照著做的文件。
雖然時間長了一點,不過協同寫作對所有人的壓力都是最低的,可以讓programmer更樂於從事文件的寫作。
要做到協同寫作,最簡單的方法莫過於使用wiki,概可讓多人同時寫作,又有版本控制,追蹤修定也非常的簡單。
Wiki的好處:
- 協同寫作
- 版本控制
- 搜尋簡便
相關閱讀
Labels:
Software Engineering
2011年5月4日星期三
This is not a bug but intended design feature
「This is not a bug but intended design feature.」
全盤接受?耍嘴皮?騙鬼?開玩笑?
這不能排除有這個可能,可是我會偏向負面的意思,畢竟Bug就如小強一樣,是讓人惡厭的東西,如果一項功能會讓別人以為是bug… well。
本人某天的晚餐,聯想力高者勿看
這句子成立的情況有許多,只是大多數情況下都不成立而已,比較常出現而又成立的應該是遊戲設計上。
例如我看過這篇文章 ﹣ “这不是Bug而是个Feature”,其中提到一個叫ExtremeG的N64賽車遊戲的的bug。
本來有一個AI來讓電腦玩家決定在何時使用Turbo超車,但因為編程錯誤讓電腦玩家變得非常之侵略性,即使在灣道也不許你超車,會立即使Turbo迎擊,結果就是一團糟的車禍意外.
測試者的評價是贊賞的!
類似的故事在遊戲業界還能找到許多,基於我不是屬於那個界別,而又不是不負責任之徒,所以還真是沒有說過這番話,解釋bug與defect倒是經驗豐富,因為許多客戶都把不存在的功能視為bug,費的力氣還真不少。
雖然沒有把bug當作過feature,不過把不可預測狀況的代碼送出去倒是做過。
在ThinkGeek或一些網站可以買到一個叫做USB Stress Game的玩意:
(ThinkGeek的示範,不過那是錯誤的,請看下去 ;) )
當年我為客戶設計了這個玩具的程式,這玩意能接駁電腦,你可以拉、推及扭這個“球”,然後電腦的畫面就會被你所扭曲。
最初的規格裹面定義4種扭曲,然後由一種扭曲轉到另一種之前要先把畫面還原。
依足要求完成後,客戶說:
「效果好像不太好...」
「那要怎樣的效果呢?」
「hmmm… 最好是不用變回原狀,直接變成其他扭曲。」(規格要修改了!要加入新的過渡動畫)
「那已經不是原來的形狀了,我們有4種扭曲,如果要加入過渡的動畫,就要多6種效果,你們要設計這6種,而我們又會很辛苦,這超越了預算,我們得...」
對方明白我們的難處,所以陷入了沉思之中。
這個動畫是利用物理模擬的方法製作的,基於當初的要求,改變扭曲必須在畫面還原後進行,所以有額外的代碼確保流程,不過因為程式架構做得好,改動的難度低,所以我提出:
「不如這樣子,我把確保畫面如規格般顯示的代碼關閉,我不能保證會發生什麼事,動畫可能會變得亂七八糟,先讓你看一看效果吧。」
花了數分鐘改寫代碼,成果如下:
從14秒開始就是多出來的效果,例如翻頁、螺旋、無限拉長、局部變大等等, 那完全是規格外、不在設計之中的效果,而且多出的效果可不祇有6種,只要按鍵的次序及時機不同便會生出現許多無法預測的動畫,就算是作者本人我也不知道 XD
結果客戶飛快地接受了這個版本,後來還把幾項控制用的代碼刪掉,在保持原來四種扭曲時,其他過渡動畫的表現更加隨機。
想不到跟規格做的東西反而是多餘的 XDDD
說了些bug / defeat變成feature的實例,也說些完全相反的混帳事。
在上文<<買Motorola手機前請先考慮清楚 (包括Atrix)>>說過我對MO記震蛋的投訴,後來又收到了一個白目的回應:
「This is not a bug but intended design feature.」
即是代表:「震蛋是功能,不是錯誤」
(回答者是一名MOTO Expert,說是volunteer,但如果沒有跟Motorola的聯絡,又那會說得出這是design!?)
到底為何MOTOROLA的設計師/高層那麼堅持手機必須在使用震個不停來虐待用家,我是完全沒有頭緒啦,說不定他們其實有什麼特殊的使用方法,是我們好孩子們不應該知道的。
作為消費者,我認為被愚弄了,別說其他公司的產品,剛是第一代Milestone就沒有這個bug,用feature來推卸責任,我唯一想到的解釋是:「那一定是用來懲罰用家的功能!」
我強烈建議Motorola還要加入播歌功能,唱:「你真是蠢!蠢!蠢!,蠢得真奇妙!妙!妙!」
概然他們堅稱那是功能,那可以想像到之後還是會有新成員作加入震蛋系列,祝各位用家好運。
Labels:
作品,
笑話,
Development,
Mobile,
Software Engineering
訂閱:
文章 (Atom)












