<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>同人的生活派對 &#187; 專案風險</title>
	<atom:link href="http://www.lifeparty.idv.tw/blog/archives/category/%e7%ae%a1%e7%90%86/%e5%b0%88%e6%a1%88%e7%ae%a1%e7%90%86/project-risk/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lifeparty.idv.tw/blog</link>
	<description>君子學以聚之,問以辨之,寬以居之,仁以行之</description>
	<lastBuildDate>Fri, 20 Jan 2012 11:19:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>敏捷開發實戰經驗分享會後感</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/2114</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/2114#comments</comments>
		<pubDate>Sun, 08 Nov 2009 00:02:52 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[問題解決]]></category>
		<category><![CDATA[學習]]></category>
		<category><![CDATA[專案團隊]]></category>
		<category><![CDATA[專案規劃]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[生活感觸]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[開發流程]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=2114</guid>
		<description><![CDATA[分享會在台北市電腦公會舉行，看到現場互動氣氛的熱絡，以及會後學員們給予不少正面的評價，感覺大家收穫都不少。其實包括我自己在分享會結束之後也產生了一些想法，倒是想藉由此文章分享我的分享會後心得。]]></description>
			<content:encoded><![CDATA[<p>上個月 24 日應 <a href="http://scmteamwork.blogspot.com/2009/10/agile-development.html" target="_blank">MaoYang 兄之邀</a>，分享我在敏捷開發的實戰經驗。這場分享會還找來了 <a href="http://www.wretch.cc/blog/kojenchieh" target="_blank">David Ko</a> 兄分享他在公司導入 <a href="http://en.wikipedia.org/wiki/Scrum_(development)" target="_blank">scrum</a> 開發管理方法的經驗，同人則負責分享我之前在專案中推行 <a href="http://en.wikipedia.org/wiki/Extreme_Programming" target="_blank">extreme programming</a> 工程實務的經驗。分享會在台北市電腦公會舉行，看到現場互動氣氛的熱絡，以及會後學員們給予不少正面的評價，感覺大家收穫都不少。其實包括我自己在分享會結束之後也產生了一些想法，倒是想藉由此文章分享我的分享會後心得。</p>
<p>同人很喜歡 David Ko 兄提到愛因斯坦為 <a href="http://www.brainyquote.com/quotes/quotes/a/alberteins133991.html" target="_blank">Insanity</a> 這個字所下的定義：「Doing the same thing over and over again and expecting different results」我認為這個定義很貼切地描寫許多人在軟體開發過程所展現的心態；過去做過行不通的做法，卻認為在今天可以行得通，結果讓人一直瘋狂或是不斷地精神錯亂。</p>
<p>但為什麼人們要盲目地做些行不通的事呢？其實以同人這麼多年軟體開發的經驗來看，他們不見得是意識不到這些做法行不通，而是可能因為害怕與恐懼，讓他們不敢嘗試新的方法來解決問題。</p>
<p>縱使無法解決問題的挫折是令人沮喪的，但如果要放棄過去習慣的做法來開發系統，他們更會茫然不知所措，擔心因此對現況失去掌控能力。於是明知過去的做法有問題，但更害怕失去它就會一無所有，於是只好將它緊緊地捉在手上，並期待這一次會有奇蹟出現，改寫過去失敗的命運。</p>
<p>不過如果人們理性一點，都會意識到要改變命運不應該期待奇蹟，而是需要「勇氣」讓我們改變心智模式，然後採用有效的方法來解決問題。在這方面，同人覺得比較幸運的是我常碰到好主管，能夠支持我想要把事情做好的想法。</p>
<p>記得過去的主管 Y.L. Liu 曾經告訴過我的話：「如果過去這樣做行不通，那今天就應該嘗試不一樣的做法」即使改變必然會遭遇到阻礙，然而當我們勇於面對阻礙而因應問題時，才能促使我們打破過去的習慣來進行有紀律地思考與行動，進而更有效地解決問題。</p>
<p>紀律，也就是 discipline 這個字。它的意義並不是做我們過去熟悉的事，而是熟悉了解問題是什麼，並加以解決問題的過程。如同我<a href="http://www.lifeparty.idv.tw/blog/archives/175" target="_blank">過去的文章</a>所強調的，軟體開發不只是工程，或是工藝，而是解決問題的過程。敏捷開發其實並非依賴制式的軟體開發流程或方法，而是基於重要價值觀與原則發展出來的實務，而最重要的價值觀就是為了思考如何「解決問題」，至於使用流程方法都只是手段而不是目的。</p>
<p>然而，根據同人的經驗，想要軟體開發過程運用以上的觀念，我認為最困難的是對專案目標的混淆。在這次的分享會之中，同人也發現有些 PMP 背景的朋友，他們很關心如何準確預估專案的範圍、時程與資源，因此希望了解敏捷開發如何來解決這樣的問題。但其實敏捷開發方法根本不需要做精確的預估，因為改變是無法預估的。所以它強調的是反應變化的能力，而不去為預期或抑制變化做太多的努力。</p>
<p>或許有人會把精確的專案預估，看成是專案成功的重要目標之一。但以同人這位 PMP 對專案管理的認知來看，精確預估並非專案的目標，而是達成降低專案風險目標的手段之一。或許用這種手段來蓋房子，或生產看得到、摸得著，可以明確度量的產品可以做得很好，但用它來開發軟體卻不見得可以行得通。</p>
<p>我們應該改變對軟體開發專案的傳統思維；假如軟體開發的本質，就是難以精確預估，那麼我們就不該將力氣浪費在預測上，而是應該用來進行對專案更有效益的事情上。但這不代表敏捷開發方式不做規劃，而是規劃的重點不在精確地預測未來，而是用來定義專案的基準線；利用每一次的反覆過程的回饋，用來改善或調整後續的計劃，以增進我們回應變化的能力。</p>
<p>因此，使用敏捷開發我們不需要具細彌遺地預測未來的改變，只需集中心力面對今天所發生的問題。換句話說，開發者也不需要一份不會變更的功能需求清單，而是了解專案目前所要解決的實際問題，進而<strong>運用</strong>(adopt)思考及創意、<strong>調適</strong>(adapt)方法然後再<strong>熟練</strong>(adept)所需要的技能來解決問題。</p>
<p>那麼，以上敏捷開發的思維是否打破專案管理的基本觀念？同人從不認為如此。依照 <a href="http://en.wikipedia.org/wiki/A_Guide_to_the_Project_Management_Body_of_Knowledge">PMBOK</a> 的專案管理知識領域與流程本來就支援管理改變的做法，問題只在於管理者是否掌握住變更管理的重要原則並熟練它們：</p>
<blockquote><p>首先、必須確認改變對專案有正面效益；</p>
<p>其次、必須確認影響變更的因素已發生；</p>
<p>最後、最重要的是管理變更。（PMI，2000）</p></blockquote>
<p>我們看到這些原則不但並不違背敏捷開發的思維，同時兩者是相通並且相輔相成的。的確，對於軟體專案而言，改變意味著增加軟體開發的風險，但害怕專案風險的心態，也代表你的團隊面對風險只能迴避它們以確保安全，但你所獲取的利潤也相對變得較低（<a title="More about Peopleware" href="http://www.anobii.com/books/Peopleware/9789867889645/01dc7d45cbe3e8fadc/" target="_blank">DeMarco &amp; Lister，2007</a>）。於是你必須辛苦地在市場上試圖降低軟體價格來與對手競爭，除非你能夠勇敢地面對挑戰，選擇快速回應變化才會創造機會，為專案產生更大的正面效益。</p>
<p>那麼對於環境或需求的變化，軟體開發團隊要如何快速回應呢？依據同人的經驗，大規模的事先設計（BDUF，Big Design Up-Front）通常無法立即迅速地反應變化，而且常常會造成過度的工程化（over engineering）的問題。而依賴開發組織導入某些流程、工具或方法論其實也並非成功的關鍵。我認為只有增進團隊溝通與合作，讓團隊能為面對問題而共同努力，才能夠快速地回應變化。</p>
<p>或許有人會認為詳盡的文件可以增進溝通，但實際上它的成效不高而且常常要人們花費很多的心力，除非你發現它真的有幫助，否則你應該只需要<a href="http://www.lifeparty.idv.tw/blog/archives/1113" target="_blank">寫必要的文件</a>。雖然工具或方法論可以增進開發的效率，但它們也會讓工作變得艱難。因為無法被替除的工作，它們是更具備知識密集的特性，需要更有才幹的人來完成任務（DeMarco &amp; Lister，2007）。所以在導入任何工具或方法論之前，你應該提醒自己，<strong>敏捷開發是以人為基礎，面對的是現實而非理想</strong>。</p>
<p>誠如 David Ko 在分享會中說得好，任何方法的導入如果最後變成政令宣導時，那就非常不妙了。同人則以為快速回應的關鍵不在於遵循方法論的做法，而在於面對專案的現實問題，讓團隊共同因應問題而改變。David Ko 提出了很多他的專案所導入的做法，同時分享他感受到團隊成員自動自發的喜悅，也讓同人希望能夠見賢思齊。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/2114"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/2114/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>如何在系統失敗前發現錯誤</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/2063</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/2063#comments</comments>
		<pubDate>Mon, 26 Oct 2009 05:40:37 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[CNet/ZDNet]]></category>
		<category><![CDATA[利害關係人]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[寫作]]></category>
		<category><![CDATA[專案團隊]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[新聞]]></category>
		<category><![CDATA[組織]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[軟體審查]]></category>
		<category><![CDATA[開發流程]]></category>
		<category><![CDATA[閱讀]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=2063</guid>
		<description><![CDATA[這篇文章是投稿 ZDNet Taiwan 的文章原稿，由 ZDNet Taiwan 以〈如何在系統異常前發現錯誤？〉、〈如何在系統異常前發現錯誤？（下）〉兩篇文章刊登。文章原稿未經 ZDNet Taiwan 編輯，內容可能與 ZDNet Taiwan 約略有所不同。 前一陣子有兩個與資訊系統失常有關，而且眾所矚目的新聞事件，也就是戴爾電腦網路購物系統與台北捷運內湖線的系統異常。相信很多人都認為這兩個系統會發生系統異常相當離譜，在系統上線之後才發現系統無法正常運作，造成系統使用者的困擾，同時也會讓人對系統可靠度與穩定度失去信心，而增加系統的失敗成本。 雖然平心而論，想要事前預料系統可能發生的問題，並加以預防或因應其實並不容易，因為開發系統，尤其是軟體開發常會碰到事先難以預料的問題。但如果能在錯誤造成危害之前，就能夠發現問題並採取適當的行動來解決它，應該就能減少系統的失敗成本。因此，看到戴爾與台北捷運內湖線的重大系統異常，讓筆者想探討如何在系統失敗前發現錯誤，以避免系統失敗的巨大損失。 設計不夠好？ 戴爾是世界知名的電腦直銷公司，擁有 13 年的網路直銷經驗。對於這種有豐富網路直銷經驗的公司來說，系統連續發生產品標價錯誤的問題，實在是一件令人感到不可思議的事情。在戴爾發生第二次標價錯誤事件之後，筆者聽到有一位工程師出身的朋友指出，戴爾筆記型電腦的標價錯誤，是因為他們的系統設計不良。他依據新聞的報導，對比自己的網站開發經驗，認為可以確定這絕對是設計的問題。研判是促銷資料沒有正確關連產品資料，才會發生這種錯誤。 從戴爾回應外界連續標價錯誤事件的說法，第一次錯誤定位為人為作業疏失，第二次錯誤是因為系統異常。這麼看來朋友的說法似乎有些道理，但從系統開發流程的角度來看，卻讓筆者產生一個疑問。如果是因為設計有問題，應該是可以在系統正式運行前被測試出來，但為什麼要直到錯誤釀成災禍才被使用者發現？朋友表示要做到完整測試系統是很困難的，還不如把系統設計做好，這樣系統自然不會出錯。 在觀念上，我同意朋友的說法，因為好的設計的確可以減少系統發生錯誤的機會。但問題是朋友的想法在實務上卻有操作上的困難。因為設計夠好是很難被清楚定義，尤其是在專案時程及資源有限的情況下，想要設計出可以在各種情況下適用的系統是非常困難的。面對系統運作環境與需求變化無常的情況下，設計通常只是一種權衡與取捨之道；沒有可以解決所有問題的最佳設計，只有針對解決重要問題的最適當設計。 如果我們不能定義出具體明確的系統問題，所謂的較好的設計也只不過對未來可能變化的假設所做的設計，但實際上未來的變化可能會出乎我們的意料之外。當我們對系統的假設不再成立時，就會產生系統可能發生異常的風險。因此，戴爾出現系統異常的原因，問題的關鍵可能並不在設計的好壞，而是沒有掌握好問題的複雜度；今天系統碰上比過去更複雜的問題，是當初設計系統之時所沒有想到的情境。 造成錯誤的原因 從筆者過去系統開發的經驗顯示，過去長期運作正常的系統，經常會因為運作環境發生變化，而使系統在現今發生功能失常。我想戴爾的情況應該也是類似的狀況，否則如果是設計有問題，就很難解釋為什麼過去運作正常的系統，會在今天出問題。如同商業周刊的評論「戴爾烏龍 在於沒換腦袋」所提到的： 戴爾系統無法偵錯的關鍵——戴爾仍以經營企業顧客的思維在做消費者生意，否則怎會沒把消費者異常下單行為納入管理流程？ 戴爾成立以來都是以企業市場為重，占營收比重超過八成。直到二○○七年才進入消費市場，這是很大的突破，因為經營企業市場，客戶數量少，強調服務與產品穩定度，但經營消費市場，客戶數倍增，就必須靈活彈性。 但此次事件讓我們看到，即使經歷兩年，戴爾網路系統的「腦袋」還沒轉過來，管理階層也是一般。 從戴爾大中華區中小企業處許肇元的說法，我們也可以了解戴爾系統異常的問題。網路上有一篇 jeremy 寫的專訪中提到許肇元對短短 10 多天連續出了兩次錯誤的解釋： 「因為我們成長的速度太快，而系統並沒有配合我們的成長。像是我們的訂購流程，每個零組件都可以客製化，訂一台筆電的流程換算下來就幾十個關卡，每個關卡都跟價錢有關，牽一髮而動全身。這次事件中，我們真的學到很多，也重新檢視了我們的系統。」 這更讓人相信，問題的關鍵並非單純的系統單一功能失常，而是戴爾忽略了商業模式改變會對系統產生影響，而沒有做好事先預防與事後可以及時因應的準備。 由此可知，造成戴爾系統發生錯誤看起來並非出在各部分功能的問題，而是系統整體整合出現問題而造成系統異常。那麼台北捷運內湖線的系統異常是不是也是相同的問題？從相關新聞報導我們發現，系統發生錯誤的原因也是因為系統沒有整合好，內湖線無法順利整合木柵線舊有系統。這大概從決策當局決定採用規格無法統一的中運量的系統，以及冒險採用無線通訊新技術時就已經註定了這樣的結果。再加上測試時間不足，自然會使品質問題更加雪上加霜而惡化。 造成系統失敗的條件 如果戴爾電腦和台北捷運內湖線的系統異常，種種跡象都顯示是整合出現問題，那麼我們不禁要問：為什麼它們的整合都會出現問題呢？從筆者系統開發的經驗來看，我相信是因為系統整合牽涉的問題太多或是太複雜，使得開發者難以掌握。再加上人們在尚未意識到系統的複雜度之前，常會認為自己有能力解決所有的問題，但實際上他們想要這樣做卻做不到。一言以敝之，系統失敗的根源其實是來自於人性的弱點，雖然這個真相往往被硬體、作業系統或平台的功能失常所掩蔽。 如同著名的軟體工程顧問溫伯格在《第一級評量》提到，造成軟體系統失敗的條件有八個 F，它是分別是弱點（Frailty）、愚蠢（Folly）、執迷不悟（Fatuousness）、好玩（Fun）、欺騙（Fraud）、狂熱（Fanaticism）、硬體功能失常（Failure）與運氣（Fate）。筆者發現這些造成失敗的條件，其實正是表現人性弱點的不同面向。 弱點 弱點是做想做的事卻做不到，它是軟體失敗的終極源頭。因為人不是完美的，他們做不到設計所要求的，不論那是一個程式設計，或是一個過程設計。溫伯格認為管理階層的責任是設計出一個程序以規範程式如何修改，承認自然界的事實，與確保程序本身被執行。而且他認為人們傾向在發生錯誤後懲罰嫌疑犯其實很不好，因為他會讓人隱藏錯誤、浪費時間在找嫌疑犯、以及分散注意力忽略管理階層的責任；建立並執行能及早找出失敗，並預防悲慘後果的程序。 愚蠢 愚蠢是做到想要做的事，但它卻是錯的事。愚蠢的基礎是無知，雖然它在當下沒有發生錯誤，卻會在以後造成錯誤。不過透過學習可以改善無知，進而將愚蠢矯正過來。溫伯格認為建立完整訓練師徒制、技術審查計劃、提供落實計劃的支援，是管理階層可以用來矯正愚蠢的職責。 執迷不悟 執迷不悟是指不肯學習，一直做出蠢事，一次又一次的做。此外，想要管理好一個愚蠢的人，卻不提供他根除愚蠢所需的訓練和經驗，這也算是一種執迷不悟的行為。溫伯格認為在軟體工程機構中，除了把執迷不悟的人送到其它行業去，否則沒有什麼防護措施可以抵擋執迷不悟的人。 好玩 好玩是程式設計師會寫一些奇怪的程式來為自己找樂子，溫伯格認為沒有人能夠預測別人認為好玩的事是什麼，因此好玩的心理是所有失敗的源頭中最危險的一個，因為它防不勝防。但管理者應該提供預防之道：一是開放透明的系統，另一個則是讓單單工作本身具有足夠的趣味。 欺騙 欺騙是用非法的方式從一個系統中獲取個人利益。溫伯格認為好玩是在失敗的源頭中，帶來的最小的損失。因為一個系統找樂子的方法有千百種，但值得一偷的東西卻沒多少。他認為軟體工程經理要好好閱讀以資訊系統詐騙為主題的文章，並採取一切可能的預防措施來防堵它。 狂熱 狂熱是試圖摧毀或瓦解一個系統，而原因不是為了個人利益，而是為了報復。溫伯格認為防範弱點而採取的行動中，多數也可以減少恐怖份子所造成的威脅與影響。 硬體功能失常 溫伯格提到硬體若不能造著當初設計的目的而執行工作，就會造成功能失常的現象，這類問題多半可以用軟體來克服。他認為當人們抱怨硬體造成他所寫的軟體出問題時，我們應該找出它表達的意思，以免遺漏這句話所帶來的重要資訊： 硬體沒什麼大不了的功能失常，但程式設計師需要找藉口來隱瞞一些事實。 [...]]]></description>
			<content:encoded><![CDATA[<p>這篇文章是投稿 <a href="http://www.zdnet.com.tw/" target="_blank">ZDNet Taiwan</a> 的文章原稿，由 ZDNet Taiwan 以〈<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20141804,00.htm" target="_blank">如何在系統異常前發現錯誤？</a>〉、〈<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20142211,00.htm" target="_blank">如何在系統異常前發現錯誤？（下）</a>〉兩篇文章刊登。文章原稿未經 ZDNet Taiwan 編輯，內容可能與 ZDNet Taiwan 約略有所不同。</p>
<p>前一陣子有兩個與資訊系統失常有關，而且眾所矚目的新聞事件，也就是戴爾電腦網路購物系統與台北捷運內湖線的系統異常。相信很多人都認為這兩個系統會發生系統異常相當離譜，在系統上線之後才發現系統無法正常運作，造成系統使用者的困擾，同時也會讓人對系統可靠度與穩定度失去信心，而增加系統的失敗成本。</p>
<p>雖然平心而論，想要事前預料系統可能發生的問題，並加以預防或因應其實並不容易，因為開發系統，尤其是軟體開發常會碰到事先難以預料的問題。但如果能在錯誤造成危害之前，就能夠發現問題並採取適當的行動來解決它，應該就能減少系統的失敗成本。因此，看到戴爾與台北捷運內湖線的重大系統異常，讓筆者想探討如何在系統失敗前發現錯誤，以避免系統失敗的巨大損失。</p>
<h4>設計不夠好？</h4>
<p>戴爾是世界知名的電腦直銷公司，擁有 13 年的網路直銷經驗。對於這種有豐富網路直銷經驗的公司來說，系統連續發生產品標價錯誤的問題，實在是一件令人感到不可思議的事情。在戴爾發生第二次標價錯誤事件之後，筆者聽到有一位工程師出身的朋友指出，戴爾筆記型電腦的標價錯誤，是因為他們的系統設計不良。他依據新聞的報導，對比自己的網站開發經驗，認為可以確定這絕對是設計的問題。研判是促銷資料沒有正確關連產品資料，才會發生這種錯誤。</p>
<p>從戴爾回應外界連續標價錯誤事件的說法，第一次錯誤定位為人為作業疏失，第二次錯誤是因為系統異常。這麼看來朋友的說法似乎有些道理，但從系統開發流程的角度來看，卻讓筆者產生一個疑問。如果是因為設計有問題，應該是可以在系統正式運行前被測試出來，但為什麼要直到錯誤釀成災禍才被使用者發現？朋友表示要做到完整測試系統是很困難的，還不如把系統設計做好，這樣系統自然不會出錯。</p>
<p>在觀念上，我同意朋友的說法，因為好的設計的確可以減少系統發生錯誤的機會。但問題是朋友的想法在實務上卻有操作上的困難。因為設計夠好是很難被清楚定義，尤其是在專案時程及資源有限的情況下，想要設計出可以在各種情況下適用的系統是非常困難的。面對系統運作環境與需求變化無常的情況下，設計通常只是一種權衡與取捨之道；沒有可以解決所有問題的最佳設計，只有針對解決重要問題的最適當設計。</p>
<p>如果我們不能定義出具體明確的系統問題，所謂的較好的設計也只不過對未來可能變化的假設所做的設計，但實際上未來的變化可能會出乎我們的意料之外。當我們對系統的假設不再成立時，就會產生系統可能發生異常的風險。因此，戴爾出現系統異常的原因，問題的關鍵可能並不在設計的好壞，而是沒有掌握好問題的複雜度；今天系統碰上比過去更複雜的問題，是當初設計系統之時所沒有想到的情境。</p>
<h4>造成錯誤的原因</h4>
<p>從筆者過去系統開發的經驗顯示，過去長期運作正常的系統，經常會因為運作環境發生變化，而使系統在現今發生功能失常。我想戴爾的情況應該也是類似的狀況，否則如果是設計有問題，就很難解釋為什麼過去運作正常的系統，會在今天出問題。如同商業周刊的評論「<a href="http://www.businessweekly.com.tw/webarticle.php?id=37222" target="_blank">戴爾烏龍 在於沒換腦袋</a>」所提到的：</p>
<blockquote><p>戴爾系統無法偵錯的關鍵——戴爾仍以經營企業顧客的思維在做消費者生意，否則怎會沒把消費者異常下單行為納入管理流程？</p>
<p>戴爾成立以來都是以企業市場為重，占營收比重超過八成。直到二○○七年才進入消費市場，這是很大的突破，因為經營企業市場，客戶數量少，強調服務與產品穩定度，但經營消費市場，客戶數倍增，就必須靈活彈性。</p>
<p>但此次事件讓我們看到，即使經歷兩年，戴爾網路系統的「腦袋」還沒轉過來，管理階層也是一般。</p></blockquote>
<p>從戴爾大中華區中小企業處許肇元的說法，我們也可以了解戴爾系統異常的問題。網路上有一篇 <a href="http://tw.myblog.yahoo.com/jeremy-3c/article?mid=33331" target="_blank">jeremy 寫的專訪</a>中提到許肇元對短短 10 多天連續出了兩次錯誤的解釋：</p>
<blockquote><p>「因為我們成長的速度太快，而系統並沒有配合我們的成長。像是我們的訂購流程，每個零組件都可以客製化，訂一台筆電的流程換算下來就幾十個關卡，每個關卡都跟價錢有關，牽一髮而動全身。這次事件中，我們真的學到很多，也重新檢視了我們的系統。」</p></blockquote>
<p>這更讓人相信，問題的關鍵並非單純的系統單一功能失常，而是戴爾忽略了商業模式改變會對系統產生影響，而沒有做好事先預防與事後可以及時因應的準備。</p>
<p>由此可知，造成戴爾系統發生錯誤看起來並非出在各部分功能的問題，而是系統整體整合出現問題而造成系統異常。那麼台北捷運內湖線的系統異常是不是也是相同的問題？從相關新聞報導我們發現，系統發生錯誤的原因也是因為系統沒有整合好，內湖線無法順利整合木柵線舊有系統。這大概從決策當局決定採用規格無法統一的中運量的系統，以及冒險採用無線通訊新技術時就已經註定了這樣的結果。再加上測試時間不足，自然會使品質問題更加雪上加霜而惡化。</p>
<h4>造成系統失敗的條件</h4>
<p>如果戴爾電腦和台北捷運內湖線的系統異常，種種跡象都顯示是整合出現問題，那麼我們不禁要問：為什麼它們的整合都會出現問題呢？從筆者系統開發的經驗來看，我相信是因為系統整合牽涉的問題太多或是太複雜，使得開發者難以掌握。再加上人們在尚未意識到系統的複雜度之前，常會認為自己有能力解決所有的問題，但實際上他們想要這樣做卻做不到。一言以敝之，系統失敗的根源其實是來自於人性的弱點，雖然這個真相往往被硬體、作業系統或平台的功能失常所掩蔽。</p>
<p><a title="More about 溫伯格的軟體管理學" href="http://www.anobii.com/books/溫伯格的軟體管理學/9789867889720/01c7ec64f7e4bf0927/"><img style="padding: 5px;" title="More about 溫伯格的軟體管理學" src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=01c7ec64f7e4bf0927&amp;time=1217763761" alt="More about 溫伯格的軟體管理學" align="right" /></a>如同著名的軟體工程顧問溫伯格在《<a title="More about 溫伯格的軟體管理學" href="http://www.anobii.com/books/溫伯格的軟體管理學/9789867889720/01c7ec64f7e4bf0927/">第一級評量</a>》提到，造成軟體系統失敗的條件有八個 F，它是分別是弱點（Frailty）、愚蠢（Folly）、執迷不悟（Fatuousness）、好玩（Fun）、欺騙（Fraud）、狂熱（Fanaticism）、硬體功能失常（Failure）與運氣（Fate）。筆者發現這些造成失敗的條件，其實正是表現人性弱點的不同面向。</p>
<p><span style="text-decoration: underline;">弱點</span></p>
<p>弱點是做想做的事卻做不到，它是軟體失敗的終極源頭。因為人不是完美的，他們做不到設計所要求的，不論那是一個程式設計，或是一個過程設計。溫伯格認為管理階層的責任是設計出一個程序以規範程式如何修改，承認自然界的事實，與確保程序本身被執行。而且他認為人們傾向在發生錯誤後懲罰嫌疑犯其實很不好，因為他會讓人隱藏錯誤、浪費時間在找嫌疑犯、以及分散注意力忽略管理階層的責任；建立並執行能及早找出失敗，並預防悲慘後果的程序。</p>
<p><span style="text-decoration: underline;">愚蠢</span></p>
<p>愚蠢是做到想要做的事，但它卻是錯的事。愚蠢的基礎是無知，雖然它在當下沒有發生錯誤，卻會在以後造成錯誤。不過透過學習可以改善無知，進而將愚蠢矯正過來。溫伯格認為建立完整訓練師徒制、技術審查計劃、提供落實計劃的支援，是管理階層可以用來矯正愚蠢的職責。</p>
<p><span style="text-decoration: underline;">執迷不悟</span></p>
<p>執迷不悟是指不肯學習，一直做出蠢事，一次又一次的做。此外，想要管理好一個愚蠢的人，卻不提供他根除愚蠢所需的訓練和經驗，這也算是一種執迷不悟的行為。溫伯格認為在軟體工程機構中，除了把執迷不悟的人送到其它行業去，否則沒有什麼防護措施可以抵擋執迷不悟的人。</p>
<p><span style="text-decoration: underline;">好玩</span></p>
<p>好玩是程式設計師會寫一些奇怪的程式來為自己找樂子，溫伯格認為沒有人能夠預測別人認為好玩的事是什麼，因此好玩的心理是所有失敗的源頭中最危險的一個，因為它防不勝防。但管理者應該提供預防之道：一是開放透明的系統，另一個則是讓單單工作本身具有足夠的趣味。</p>
<p><span style="text-decoration: underline;">欺騙</span></p>
<p>欺騙是用非法的方式從一個系統中獲取個人利益。溫伯格認為好玩是在失敗的源頭中，帶來的最小的損失。因為一個系統找樂子的方法有千百種，但值得一偷的東西卻沒多少。他認為軟體工程經理要好好閱讀以資訊系統詐騙為主題的文章，並採取一切可能的預防措施來防堵它。</p>
<p><span style="text-decoration: underline;">狂熱</span></p>
<p>狂熱是試圖摧毀或瓦解一個系統，而原因不是為了個人利益，而是為了報復。溫伯格認為防範弱點而採取的行動中，多數也可以減少恐怖份子所造成的威脅與影響。</p>
<p><span style="text-decoration: underline;">硬體功能失常</span></p>
<p>溫伯格提到硬體若不能造著當初設計的目的而執行工作，就會造成功能失常的現象，這類問題多半可以用軟體來克服。他認為當人們抱怨硬體造成他所寫的軟體出問題時，我們應該找出它表達的意思，以免遺漏這句話所帶來的重要資訊：</p>
<ol>
<li>硬體沒什麼大不了的功能失常，但程式設計師需要找藉口來隱瞞一些事實。</li>
<li> 硬體功能失常問題都在一般的預期範圍內，可能程式設計師沒有採取正確的防護措施。例如將程式碼或測試腳本做備份。</li>
<li>硬體功能失常，但沒做好硬體供應商關係的管理工作。</li>
<li>硬體功能失常是由人為錯誤所造成的，如使用者做出出乎意料的動作。</li>
</ol>
<p><span style="text-decoration: underline;">運氣</span></p>
<p>溫伯格指出運氣不好是多數表現不佳的經理愛用藉口，這不是事實。他建議當我們聽到一個經理老愛說運氣不好時，我們應該把運氣兩字換成經理，因為沒有不好的士兵，只有不好的軍官。</p>
<h4>系統異常與人性弱點</h4>
<p>從以上造成系統失敗的條件我們可以知道，系統發生異常的原因可能是系統的設計不夠好、硬體設備或作業系統出錯或是系統運作的環境太複雜了，但發生問題的真相卻都大部份是因為人性的弱點。因此，要在失敗前發現錯誤，進而採取行動防止系統失敗，重點管理好人性弱點，而非不承認它的存在，卻只在事後責備人們沒有盡到責任，但事實上最大的責任是管理階層沒有盡到管理的責任。</p>
<p>例如在台北捷運內湖線在 7/10 發生系統大當機的事件後，當外界質疑為什麼發生這麼嚴重的當機事件時，筆者注意到有一篇新聞報導提到市府官員有人表示「這個問題，80 % 是因為電腦中毒」言下之意系統異常多半是因為硬體的功能失常所致，而比較不可能是軟體的瑕疵或人為的錯誤。</p>
<p>溫伯格說過「對錯誤的直接觀察，本身並無意義，但是對『人們作何準備來面對錯誤的發生』的統合觀察就很有意義」那位市府官員的說辭，筆者相信只是為了隱瞞了一些事實，以免公布實情而讓損失更加擴大，然而這卻表現反應他們對面對系統錯誤發生的準備並不夠充分。</p>
<p>筆者再舉一位朋友的經驗為例，以前他們公司採用 .Net 開發平台開發新產品。由於他偏好 Java 的程式寫作慣例，加上當時微軟聲稱與 C# 整合不成問題，讓他很想用 J# 程式語言來開發系統。雖然他的同事擔心系統的整合會出現變數而反對，但由於他的堅持，管理階層還是照他的意思，讓他用 J# 開發他的程式，與其他同事以 C# 的程式來進行整合。</p>
<p>後來在整合時，他們發現碰到很多平台上及程式語言本身的問題。為了解決這些問題，他只好修改他的程式以處理這些問題，但也讓系統愈變愈複雜，結果使軟體問題層出不窮。但朋友仍然還是堅持要用他喜歡的方式開發系統，最後在管理階層無法忍受他的執迷不悟，並且在彼此無法達成共識的情況下，要求他離開了那家公司。</p>
<p>從這位朋友的故事中，我們看到他的弱點、愚蠢以及他和管理階層的執迷不悟。他的弱點是想實現他的設計理念並完成不同語言的整合，但後來卻發現這是個艱鉅的任務。在發現了專案時程及市場上的壓力並不允許他實現他的設計理想時，卻一再地堅持做自己想做的事而非應該做的事，這是愚蠢。而與管理階層之間一次又一次想要對方同意自己的觀點，卻又不去理性客觀地評估現實，而只是一廂情願地以為讓對方發現此路不通就會懸崖勒馬，這是他與管理階層的執迷不悟。</p>
<p>朋友的經歷並不是特例，在實際的系統開發專案中，筆者總是看到相同的故事正在持續上演。就像戴爾電腦、台北捷運內湖線發生系統異常的事件一樣，應該發揮效果的程序、流程與方法，在關鍵時刻竟然沒有發揮作用。筆者認為問題的關鍵是在於人性的弱點，我想只有在適當地管理好人性弱點之後，程序、流程與方法才能真正地落實，並且發揮出應有的效果吧。</p>
<h4>管理的重要性</h4>
<p>如果導致系統異常的關鍵是在於人性的弱點。那麼管理階層就應該負起管理人性弱點的責任，以避免專案因為人性弱點而造成系統異常的意外事件而慘遭失敗。從去年跨年夜發生的台灣大哥大行動電話用戶大當機的<a href="http://udn.com/NEWS/SOCIETY/SOC7/5110638.shtml" target="_blank">事件</a>，又再一次地讓我們看到管理對避免系統異常而造成失敗的重要性。</p>
<p>去年跨年夜，台灣大哥大發生行動電話用戶大當機，經檢調查出是台灣諾基亞西門子公司離職工程師，涉嫌以女友名義登入台灣大資料庫並刪除資料造成大當機，檢方昨天將陳依妨害電腦使用罪嫌起訴。</p>
<p>筆者看到新聞提到那位工程師，否認是遭開除而挾怨報復，只說會這麼做是因為「好玩」。讓我想到溫伯格說的，好玩的心理是所有失敗源頭最危險的一個，因為沒有人可以預測到別人認為好玩的事是什麼。</p>
<p>當然，我想事件的真相應該不是因為那位工程師基於好玩的心理，而是被公司開除而心生報復。造成台灣大哥大系統當機的原因，固然是難以預料到的惡意破壞，但這並不代表這種系統失敗是無法防止的。筆者認為問題在管理上，因為管理階層忽視人性弱點，而沒有盡到管理者應盡的責任。</p>
<p>或許有人會認為筆者這樣說對管理者要求太多了，但如果系統開發團隊沒有紀律來把事情做好，這的確是管理者的問題。管理者設計或制定流程，目的是為了幫工程師把事做好，但如果流程不能落實，那是必然代表管理出現了問題，所以管理者必然難辭其咎。</p>
<p>好比說，為什麼離職員工可以用他離職前的帳號密碼來登入系統，然後做出一些危害系統的行為？又或者，為什麼會讓人興起想要破壞系統的動機，而身為負責系統成敗的高階管理者，為什麼會不去防範可能破壞系統的行為？</p>
<p>因此，即使可能是因為好玩，管理者也要思考如何降低人們為了找樂子而影響系統的動機。如前面所提到過的，讓員工的工作更有趣，同時讓流程更透明。此外，避免員工試圖摧毀或瓦解一個系統，不是為個人利益而是為了報復。管理者應加強防範弱點而採取的行動，因為它們多數也可以減少這種攻擊。</p>
<p>以上這些都是管理者的職責，以避免系統因為人為的疏忽而失敗。總而言之，預防系統失敗，管理最重要的工作就是認清「人的不完美」，才能知道如何管理人性，進而避免發生人為錯誤而造成意外，產生系統的重大損失。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/2063"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/2063/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>強迫新手這麼做的風險</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/1281</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/1281#comments</comments>
		<pubDate>Fri, 07 Aug 2009 09:26:26 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[分析設計建模]]></category>
		<category><![CDATA[利害關係人]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[寫作]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[生活感觸]]></category>
		<category><![CDATA[組織]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[領導]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=1281</guid>
		<description><![CDATA[同人看 Kenming Wang 這篇文章覺得怪怪的，倒不是不贊同他對寫好使用案例好處的觀點，而是覺得強迫新手去做我們認為有價值的東西是很危險的。 ]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.kenming.idv.tw/">Kenming Wang</a> 在〈<a href="http://www.kenming.idv.tw/what_is_the_befenifs_of_the_use_case">寫好使用案例 (Use Case) 有什麼好處？</a>〉中提到寫好使用案例的好處。文章提到有位其中一位較為資深的程式開發人員在他在工研院授課時表示感覺不到寫好使用案例有什麼好處。這問題讓他思考許久後回答，他認為寫好使用案例最直接的關鍵是，影響整個專案開發流程的節奏。</p>
<p>這篇文章分享他對寫好使用案例對專案好處的看法，他總結使用案例的好處是族繁不及備載。並提到越大規模的專案，更能感受到開發節奏的順暢度。再加上 "漸進循環 (incremental and iteration)" 的開發模式，會越形容易謀和在系統開發期間，人與事的種種。</p>
<p>不過，Kenming Wang 在文章最後提到以上的論述不能說服那位程式開發人員，因為程式設計人員多半以局部或個別的角度來看系統開發，所以使用案例寫得好不好，對他們沒差。只有像專案經理或軟體架構師以專案整個全局來看時，才會有明顯的感受。</p>
<p>但他認為不需要去說服那位程式開發人員，並引述 Martin Fowler 在《UML Distilled》一書中曾經說過的：「你只能強迫新手們這麼做。過了幾年後，他們會突然恍然大悟，然後腦袋彷彿重生！」這句話來說明他對這位程式開發人員意見的看法。</p>
<p>同人看 Kenming Wang 這篇文章覺得怪怪的，倒不是不贊同他對寫好使用案例好處的觀點，而是覺得強迫新手去做我們認為有價值的東西是很危險的。</p>
<p>因為這些主觀價值如果不能以客觀的方式來表達甚至衡量，這些只會造成實際執行開發工作的人的困擾，不知道所謂的「好」或「對」的作法，到底與他們的工作有什麼直接關係，如此只會使他們工作變得更複雜。如果未來真能讓他們恍然大悟而腦袋重生倒也還好，但如果最後發現期望落空，是否只是浪費開發工作者寶貴的時間和精力呢？</p>
<p><a href="http://www.anobii.com/books/UML精華第三版/9789861540399/000a9259120e772e7a/" title="More about UML精華第三版"><img src="http://image.anobii.com/anobi/image_book.php?type=4&#038;item_id=000a9259120e772e7a&#038;time=0" title="More about UML精華第三版" align=right alt="More about UML精華第三版" style="padding: 5px;" /></a>尤其同人很懷疑 Martin Fowler 會說「你只能強迫新手們這麼做」的話。當然，同人對「腦袋重生」有印象，但記得不是出現在使用案例的章節，而是出現在循序圖的章節中，提到集中式或分散式物件設計的不同思維。果然，同人回家翻閱譯者光正兄送我的《<a href="http://www.anobii.com/books/UML精華第三版/9789861540399/000a9259120e772e7a/" title="More about UML精華第三版">UML精華第三版</a>》發現，在循序圖的章節有下面這一段文字。</p>
<blockquote><p>這種設計風格的改變正是物件導向設計典範革命的核心所在。不過，這也是難教導之處。真正了解物件導向典範唯一方式似乎就是在強烈使用分散設計風格的OO環境工作一陣子。許多人會突然恍然大悟，開始理解到這種設計風格究竟為何。這時候，他們的腦袋將重獲新生，也開始比較容易思考分散控制的設計風格。（趙光正譯，2004，《UML 精華第三版》，「Chapter 4 循序圖」，p4-6）</p></blockquote>
<p>同人知道 Kenming Wang 是很聰明的顧問，懂得舉一反三引用大師的觀點來強化自己的論點。但用在此處看來有斷章取義之嫌，而且非常危險，我認為這很容易淪為方法論的主觀價值批判。因為不管怎麼說，如果光正兄的翻譯沒有錯誤的話，文句的原意並沒有貶抑不同開發觀點的意味。</p>
<p>同人以為問題的關鍵並不在某種開發典範有何好處，所以應該強迫他們採用、適應、進而熟練方法進而讓專案獲益。而是在於強迫導入任何方法論都會存在風險，我們是否能夠充分理解這些風險對專案產生的影響，以及所付出的代價是否值得。或許你還會有印象，同人在〈<a href="http://www.lifeparty.idv.tw/blog/archives/982">簡單，複雜世界的致勝之道</a>〉分享過複雜面向的最主要來源是變革欠缺整合。</p>
<blockquote><p>高層主管與員工對整合觀點的懸殊態度，對於整合，領導者關心的焦點是管理、控制與協調的工具；而員工關切的重點是有利個人決策的工具，執行工作者的觀點常會受到不平等的對待。</p></blockquote>
<p>從這裡我們可以很輕易地了解，為什麼很多使用案例方法的導入常使軟體開發人員的工作變得更複雜。可能你會說那是因為誤用使用案例，或是沒有寫好使用案例，但其實依據同人的觀察，造成誤用或使用案例的不良寫作多半是因為不同觀點的差異，進而導致彼此的溝通不良所致。</p>
<p>站在全局觀點的人總是認為沒問題，但實際上他們並不能提供局部或個別觀點足夠的資訊，以利其進行開發上的決策。而往往為了符合全局觀點的架構上的框架，往往要逼著程式開發人員削足以適履。</p>
<p>請不要誤會，同人並非否定寫好使用案例的好處。事實上，從我過去的工作經驗，我很能體會寫好使用案例的好處，只不過我從來不認為好的使用案例可以解決不同觀點的整合問題；其實沒有任何的文件可以做到這點，除非允許各種聲音充分表達，然後進行相互對話以提昇溝通品質。</p>
<p>為什麼沒有任何文件可以解決不同觀點的整合問題呢？因為不管文件所傳達的觀念多麼「好」或是「正確」，而沒有與其他的觀點進行互動與溝通，進而分享意義，很容易讓各種不同的觀點各說各話，而無法促成彼此的思考與反省，進而激發出可以解決問題的智慧。所謂的「好」或是「正確」只是基於已知最佳實務的記憶，而不是為了解決複雜問題的思考，因此不見得可以有效地因應問題反而使問題更加複雜化。</p>
<p>不同觀點的整合，這絕不是「強迫新手這麼做」就可以成功的。你會需要實際執行工作者的回饋，了解他們的問題與期望，才能幫他們更簡單的完成工作，才不會因為忽略程式開發人員觀點的思慮不周，使工作變得更複雜而浪費他們的時間與心力。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/1281"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/1281/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>穩定的程式是偶然？</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/421</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/421#comments</comments>
		<pubDate>Fri, 09 Jan 2009 06:54:09 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[學習]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案規劃]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[編程技巧]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[設計原則]]></category>
		<category><![CDATA[開發流程]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/421</guid>
		<description><![CDATA[如果穩定的程式真的是偶然的，程式的穩定似乎只能依賴運氣而不是人為努力，事情真的是這樣嗎？其實這位噗友太過強調環境變化的隨機性，卻忽略了適應環境變化，程式開發必然會經歷複雜演化的過程。穩定的程式是演化而來的，雖然演化的過程是偶然、但其最後結果卻是必然。換句話說，穩定的程式是偶然下的必然。]]></description>
			<content:encoded><![CDATA[<p>最近同人看到有<a href="http://www.plurk.com/p/cayqt">一則噗浪</a>提到「一個穩定的程式並非必然，而是偶然」在此噗浪的回應中，發送這則噗浪的噗友表達他對程式穩定性的看法。</p>
<blockquote><p>先問自己一個問題，一個程式有幾個 Bugs？如果是不可數，那～～它的穩定是相對非絕對，所以穩定不是絕對的，也不是必然的。</p></blockquote>
<p>同人覺得這位噗友的觀點很有趣，於是加入這則噗浪的討論。我問如果最開始的程式都是穩定的，那麼是什麼原因讓後來的程式變得不穩定？對這個問題，一些噗友提出了他們的看法，其中有一位噗友回應「是我的機器弄好的程式，跑到別人機器就不穩定了」，發送此則噗浪的噗友認為還蠻接近實際的情形。</p>
<p>他提到 Bugs 在自己的機器沒產生，在別人那邊可能會產生，問題可能是因為自己的機器有 Bugs，而不是別人的機器，他說假設機器不會出問題是會有副作用的。</p>
<p>那麼為什麼不在應用系統要運作的目標環境下直接開發程式呢？因為，嚴格來說，開發者不可能有完全一致的環境，因此開發者只能假設環境是不會改變。但實際上，在不同的機器上、甚至在相同的機器上，不同的時間可能也會出現難以預料到的變化，結果使得程式變得不穩定。</p>
<p>這位噗友認為，當我們愈信任一個系統，其實可能是一個災難，因此程式的穩定非絕對而是偶然，它是由一連串的偶然所累積而成的。同人發現這個觀點讓人很難反駁，在我過去程式開發的經驗中，並不乏遇到原來運作正常的程式，在不同時空環境出現問題的現象。正如同這位噗友提到的，作業系統與程式語言它們本身也都是程式，很難確保它們不會出問題。</p>
<p>相信很多人都曾遇到過，程式發生失常通常只因為一個令人難以捉摸的小錯誤，因此似乎真的可以說「穩定的程式是偶然的」。不過，如果穩定的程式真的是偶然的，程式的穩定就只能依賴運氣而不是人為努力，事情真的是這樣嗎？其實這位噗友太過強調<strong>環境變化</strong>的隨機性，卻忽略了適應環境變化，程式開發必然會經歷<strong>複雜演化</strong>的過程。穩定的程式是演化而來的，雖然演化的過程是偶然、但其最後結果卻是必然。換句話說，穩定的程式是<strong>偶然下的必然</strong>。</p>
<p>程式的運作通常需要處在多變的環境中，使得開發者很難確知他的程式有多少 Bugs。因此在本質上，程式開發過程是一個偶然，由一連串的隨機事件所構成的。雖然開發者可以使用與將來應用系統所運作環境相同的硬體及作業系統，但實際上終究並非同一台機器。它們可能會因為使用者的差異，而安裝了無法與應用系統相容的軟體或設定了會使系統出現問題的系統組態。就算是兩台機器能夠完全一模一樣，時空環境的變化也可能造成系統運作出現問題的關鍵，即使兩者的差異相當微小。</p>
<p>以上的現象就是程式開發的「<a href="http://en.wikipedia.org/wiki/Butterfly_effect">蝴蝶效應</a>」，就像天氣很難預測準確的道理一樣。一隻蝴蝶在巴西輕拍翅膀，會使更多蝴蝶跟著一起輕拍翅膀，最後將有數千隻的蝴蝶都跟著那隻蝴蝶一同振翅，其所產生的巨風可以導致一個月後在美國德州發生一場龍捲風。這是「<a href="http://en.wikipedia.org/wiki/Chaos_theory">混沌</a>」理論所討論的現象，未來的狀態對<strong>初始條件敏感</strong>而造成無法預測。在混沌系統中，初始條件十分微小的變化，經過不斷放大，對其未來狀態會造成極其巨大的差別。<sup>[<a href="http://www.lifeparty.idv.tw/blog/archives/421#footnote_0_421" id="identifier_0_421" class="footnote-link footnote-identifier-link" title="維基百科編者 (2008). 混沌理論. Wikipedia, . Retrieved 03:15, 1月 9, 2009.">1</a>]</sup></p>
<p>除非所有 Bugs 都出現為止，否則程式開發者不會知道他的程式有多少 Bugs。因為他無法預測他的機器和實際運作的機器，有那些差異會造成程式運作出現功能失常。而且問題可能不是因為他的程式錯誤，有時候問題是出在作業系統或程式語言本身的 Bugs；它們都是程式，只要程式都有可能會有 Bugs。</p>
<p>現實真是令人沮喪呀，如果不確定因素使得環境變得如此難料，那要如何期待穩定的程式出現呢？我們不能期待環境不再變化，因為軟體開發的現實就是變化無常，唯一不變的真理就是變。我們也不能不去面對問題，進行規劃及管理，因為隨性地處理問題，只會讓問題變得更加混亂而讓情況失去控制。我們應該讓系統可以 <strong>適應環境的變化，發展出兼具穩定與彈性的程式</strong>，這樣我們就能在<a href="http://en.wikipedia.org/wiki/Edge_of_chaos">界於混亂與穩定的過渡地帶</a>中，逐步演進出複雜的行為來維持整體系統的動態平衡。</p>
<p>這就是<a href="http://en.wikipedia.org/wiki/Complexity_Theory">複雜理論</a>的<a href="http://en.wikipedia.org/wiki/Complex_adaptive_system">複雜適應性系統</a>的觀念，系統透過<a href="http://en.wikipedia.org/wiki/Self-organisation">自我組織</a>來穩定自己，不會因為無法控制混亂而崩解為混沌一片，同時也保有足夠變化的彈性來進化系統行為。就像同人在<a href="http://www.lifeparty.idv.tw/blog/archives/87">過去的文章</a>中，曾經提出複雜系統來比喻專案管理的隱喻一樣，複雜適應性系統的演化過程是不斷經歷觀察、假設、調整、再假設的重覆循環過程。</p>
<blockquote><p>整個專案環境所能供給的資源是有限的（成本限制），而演化競爭者會和我們爭奪這些有限資源（時間限制），所以對一個複雜系統而言，必須達成演化的使命而創造對整體系統的價值最大化（規模限制）。要做到這點，複雜系統必須能依現狀來演化系統，用最經濟的方式創造最大的價值（技術限制），演化則是先對環境的做出假設，然後依據適者生存不適者淘汰的原則來進行演化，過程中會不斷地修正對環境的假設並改變系統行為以求適應環境。</p></blockquote>
<p>因此，對於程式開發的專案當然也是相同的道理，演化的過程是無法預料的隨機行為，但演化的結果卻是必然的；發展出最適應環境及產生最大價值的穩定系統。假設的目的是為了做到將廣大的可能性限制在一小部分，這是同人在<a href="http://www.lifeparty.idv.tw/blog/archives/175">另一篇文章</a>引用 Peter Ho 所提到讓系統停留在混沌邊緣必須做的三件事之一。另外兩件事則是必須保持足夠的穩定，即使有輕微的改變，系統仍不會崩解成混沌一片、以及必須在靜止不動的死寂與過度活動的「混亂政體」間達到平衡。</p>
<p>這也就是同人提出先前穩定的程式，最後卻變得不穩定，到底問題是出在什麼地方？問題並不在我們對環境做出假設，而是無法意識到假設所帶來的風險，以讓開發程式停留在混沌邊緣以達成系統的動態穩定。因此，噗友提到假設會有副作用的問題不在假設，而在於開發者面對環境的反應的變化太慢，以致於造成局面的紊亂而使得問題無法收拾。</p>
<p>然而，如何及早反應環境的變化維持程式的穩定與彈性呢？同人推崇測試、重構與整合三項實務，誠如 Peter Ho 所說的「未經<strong>重構</strong>，系統將會沒有空間來容納新功能來適應新的變化驅力；未經<strong>測試</strong>，開發者不會知道系統邊緣在那裡；未經<strong>整合</strong>，生命火光將逐漸消散。」用紀律來維持系統彈性與穩定，雖然環境的變化是無可預料的，但我們仍將體會到穩定的程式是偶然下的必然！</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/421"  size="standard"   ></g:plusone></div><br />附註
&nbsp;<hr/><ol class="footnotes"><li id="footnote_0_421" class="footnote">維基百科編者 (2008). <a href="http://zh.wikipedia.org/w/index.php?title=混沌理论&amp;oldid=8808028">混沌理論</a>. Wikipedia, . Retrieved 03:15, 1月 9, 2009.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/421/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>軟體缺陷的信用創造</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/395</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/395#comments</comments>
		<pubDate>Thu, 23 Oct 2008 10:04:34 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[利害關係人]]></category>
		<category><![CDATA[品質文化]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[學習]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[生活感觸]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[閱讀]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/395</guid>
		<description><![CDATA[專案經理利用軟體缺陷的創造信用來進行短期信用的流通，把 bug fixing 變成 feature request 的好處就等同於創造增加軟體開發修改 bug 代價的貨幣。然而，把 feature request 變成信用商品的後遺症，正是讓信用生產結構的迂迴，使信用崩潰延遲發生。]]></description>
			<content:encoded><![CDATA[<p><a href="http://jonathanspeaking.blogspot.com">喲哪桑</a>學長最近寫了一個有趣的故事，並在故事的後面問讀者「<a href="http://jonathanspeaking.blogspot.com/2008/10/feature-request-or-bug-fixing.html">Feature Request, Or Bug Fixing?</a>」這個故事引發了許多人進行廣泛的討論。</p>
<p>有人站在專案經理的角度來<a href="http://jonathanspeaking.blogspot.com/2008/10/feature-request-or-bug-fixing.html?showComment=1224592500000#c3831315986795217210">與故事中的 M 持相同的看法</a>，只要加強 Error handling 改掉 bug 就夠了，不需要再多花工夫來回應 feature reguest。但也有人站在工程師的角度主張<a href="http://jonathanspeaking.blogspot.com/2008/10/feature-request-or-bug-fixing.html?showComment=1224605640000#c5459001659613237877">支持故事中 Q 的想法</a>，解決問題本來就是 bug fixing，而修改問題所採用的做法只是 work around，而不是故事中 M 所說的這是 feature request。</p>
<p>不過同人覺得這個開放式的案例討論最有趣的部分，倒不是誰的看法才是正確的討論，而是看到 scarfman 「<a href="http://jonathanspeaking.blogspot.com/2008/10/feature-request-or-bug-fixing.html?showComment=1224650460000#c8017794734316698752">開版圖就已經說明了，bug 穿上衣服就變成 feature 啦！</a>」的回答，這促使同人進一步地思考到一個新觀點；也就是軟體缺陷的信用創造。</p>
<p>如果讓 bug 穿上衣服就變成了 feature，那麼我們就可以讓穿上 feature 衣服的 bug，讓人不會感到那麼難以忍受。但如果在未來，我們又發現又出現了一個新的讓人難以忍受的問題時，我們是不是再讓它套上一件新衣服來降低人們不快的感受，以解決問題呢？</p>
<p><a href="http://www.anobii.com/books/01ed4e52005036989d/" title="更多關於你想通了嗎？"><img src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=01ed4e52005036989d&amp;time=0" title="更多關於你想通了嗎？" alt="你想通了嗎？的圖像" style="padding: 5px" align="right" border="0" /></a>寫到這裡，不由得讓同人想到《<a href="http://www.anobii.com/books/01ed4e52005036989d/">你想通了嗎？</a>》中的故事，那個讓大樓住戶難以忍受的電梯。對於大樓電梯太慢的 bug，有人想到了解決問題的方法要嘛讓問題消失、要嘛減輕人們對問題發生之後的觀感，所以他想辦法讓人們在等電梯的時候不會感到無聊而解決了電梯太慢的問題。</p>
<p>但後來沒想要最後在這個解決方案所產生的新問題，卻間接害死大樓的房東先生，使他意外喪生。最後才由電梯維修人員才發現電梯變慢的原因並加以解決（故事很精采喲，沒看過的強烈建議你去看）。</p>
<p>實際的軟體開發好像也跟那個大樓電梯的故事一樣，「當程式出現功能失常的時候，想辦法避開它就行了嘛，不用浪費時間對不重要的 legacy bug 增加 feature」或許就因為這種心態，讓軟體的缺陷不斷地四處擴散，使得 bug 好像沒有改完的一天。甚至發生了「<a href="http://www.lifeparty.idv.tw/blog/archives/308">總是要到驗收前，才發現程式有問題？</a>」這類的悲慘事件。</p>
<p>正巧同人最近看了石頭成最近寫的文章，提到<a href="http://blog.roodo.com/rocksaying/archives/7414551.html">衍生性金融商品「信用創造」的古老詞彙</a>，我發現軟體開發與財務金融雖然領域不同，但以金融的信用創造相同的觀念似乎可以用來解釋軟體缺陷的信心崩潰。畢竟經濟學是用來解釋社會現象，而軟體專案開發其實並不脫離經濟學可以解釋的範疇。</p>
<p>從石頭成引用的文獻資料可以理解，商業銀行的所謂「信用創造」之所以可能，只是因為短期信用的流通等於貨幣的流通。因此，創造信用就是創造貨幣。而石頭成還提到信用生產結構的迂迴，使得任一信用商品的崩潰，會延遲反饋。</p>
<p>用同樣的邏輯來看，專案經理利用軟體缺陷的創造信用來進行短期信用的流通，把 bug fixing 變成 feature request 的好處就等同於創造軟體缺陷貨幣的流通。然而，把 feature request 變成信用商品的後遺症，正是讓信用生產結構的迂迴，使信用崩潰延遲發生。所以我們在即將驗收時才發現 bug 改不完，其實是一種信心崩潰的必然結果。</p>
<p>就像學長文章那位與故事中專案經理 M 持相同看法朋友的觀點會認為，<a href="http://jonathanspeaking.blogspot.com/2008/10/feature-request-or-bug-fixing.html?showComment=1224634500000#c3797666466596064734">bug 是一定要改的，否則就會變成了父債子還</a>。這樣看起來，似乎由專案上階段所遺留下來的 legacy bug 都不是 bug，而是 feature request。</p>
<p>但我們卻會在實際的專案中看到「債留子孫」的事實；我們只要問一問那些實際動手改 bug 的工程師，「bug 為什麼愈改愈多？」就知道，工程師實際上擔負了龐大的軟體缺陷債務，這些都是因為由前人不斷累積而來。</p>
<p>這些債務是如何累積來的呢？在 bug 實在太多的情形下，專案經理沒有足夠的資源與時間可以達到目標。但自認聰明的專案經理想到了一個辦法，只要讓那些 bug 穿上 feature request 的衣服，就可以帶給客戶一個美麗的遠景。使他們允許團隊向專案下一階段借貸時間與資源，並達到讓專案先行驗收的目的。</p>
<p>換句話說，feature request 意味著一種信用創造，可以增加軟體缺陷貨幣的流通，也就是增加了專案團隊的流動負債，以用來支應即將到期的信用負債。</p>
<p>顯然這將會讓專案團隊陷入了以短支長的窘境，而且對軟體缺陷，沒有「<a href="http://jonathanspeaking.blogspot.com/2007/03/blog-post_07.html">早期發現，早期治療</a>」的結果，是必須付出龐大的代價。</p>
<p>例如<a href="http://www.lifeparty.idv.tw/blog/archives/262">工程師在眼前問題緊迫的情況下，選擇自廢武功</a>，因而降低軟體的結構性使得 bug 愈改愈多，更不用說工程師的士氣與能力的低落了。等到工程師負擔不起龐大的 bug 負債時，信心崩潰就出現了，這時乙方認定的 feature request 就不會再被甲方所信任而接受了，就正如同人在〈<a href="http://www.lifeparty.idv.tw/blog/archives/391">專案不確定感的焦慮與迷思</a>〉所舉出的真實案例。</p>
<p>學長這篇故事寫得真是棒呀，雖然在他的文章開頭一再地宣稱「保證絕無添加任何教育意義之成份」，但我倒是覺得是一篇文字淺顯易懂又寓有深意的文章，值得讓我在此推薦，供大家細細品味與欣賞。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/395"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/395/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>專案不確定感的焦慮與迷思</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/391</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/391#comments</comments>
		<pubDate>Tue, 21 Oct 2008 02:09:30 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[CNet/ZDNet]]></category>
		<category><![CDATA[佛法]]></category>
		<category><![CDATA[利害關係人]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[學習]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案規劃]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[生活感觸]]></category>
		<category><![CDATA[職場]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/391</guid>
		<description><![CDATA[本篇文章是投稿 ZDNet 的文章原稿，並以〈專案不確定導致焦慮與迷失〉與〈專案不確定性導致焦慮與迷失(下)〉兩篇文章刊出。原稿未經 ZDNet 編輯，其內容可能會與刊登的文章內容有約略的不同。 專案經理常會面臨天人交戰的情境。當專案「計劃總是趕不上變化，變化總是比不上老闆的一句話」之時，許多專案經理總是會擔心專案無法如期完成或害怕資源不足，而拒絕或延後專案變更的要求。但這樣的行為，卻往往造成工作成果無法符合專案實際需要的結構性因素，而使得專案的失敗機會大為增加。這對於具備智慧及膽識的專案經理而言，當然並不會樂見專案發生這樣的事情。 筆者前一陣子看到喲哪桑在〈換了屁股，我也換了腦袋〉的分享，提到他在時間緊迫的情形下，接受了專案的功能變更要求。那個變更要求原來是由他所提出，當時前任專案經理以時程緊迫為由而答應延後處理，而一直到他接任專案經理仍然還留在原處。但他認為他不能任由「行為造成結構」的情形發生，於是決定不要再讓這個專案變更要求再次拖延下去，並在當下對專案進行變更。 筆者認為喲哪桑的作為令人激賞，並且覺得那篇文章值得推薦。其原因並不是因為他針對專案變更做了什麼樣的決定，而是欣賞他在決策過程中，展現出面對自己的勇氣與解決問題的思考。不過，卻有其他讀者對那篇文章抱持相反的意見。 某位網友對喲哪桑的分享，批評他是靠感情衝動來管理專案，甚至用了「發瘋了你」、「不適任該離開的時候」等情緒性的字眼來指責喲哪桑的不是。他指出喲哪桑的文章所傳達的意念，實在有不可思議的謬誤，並且擔心那篇文章會透過 ZDNet 的報導，將不正確的知識與觀念誤導一般社會大眾。 然而，他對這篇文章的批評卻使人感到困惑，那位網友認為喲哪桑文章傳達的意念有不可思議的謬誤，但看在專業人士眼裡，這樣的觀點又何嘗不是相當嚴重的偏頗呢？筆者認為他的觀點傳達的意念本質上是一種面對不確定性的焦慮感，進而對改變的抗拒而產生無知的迷惘。 專案變更的基本原則 身為專案經理固然不應該因為個人一時的感情因素而使專案陷入危險之中，但在對專案缺乏可供客觀評論資訊的情況下，只憑專案經理接受專案變更的決定，就加以批判其決策感情衝動是否真的恰當？專案管理並不是神學或是玄學，而是屬於管理科學的範疇。因此，如果有人要批評某個專案經理是用感情衝動來管理專案，必須提出具體的事實根據，否則那只是無憑無據的推論而已，而這樣的推論多半只是源自於自我的偏見與扭曲。 以專案變更管理的原則來看，依據《PMBOK》的說明，專案經理在管理專案變更的時候，必須注意三件事。首先他必須確定變更對專案的影響有其正面的價值；其次，他必須確認造成專案變更的因素已經發生；最後，他必須對變更加以管理。 從以上的原則我們可以發現，專案經理決定接不接受專案變更的要求，不應該源自於個人的主觀認定，而是必須經過客觀的評估。只有在蒐集了專案變更的各種相關資料，並加以評估之後，我們才能確知在專案現狀下，變更的正面效益或負面影響為何、到底值不值得立即採取行動來進行變更。而在未經評估之前，沒有人可以作出專案是否應該接受、拒絕或延後變更要求的決定。 喲哪桑的文章並沒有提到他所進行的專案變更並未經過事前的評估。相反地，他在對該位網友情緒漫罵性的言辭感到莫明其妙的文章中提到，在部落格發表的文章中，他不能揭露太多工作細節，並且提到了在重提該項專案功能變更要求之前，提出者已經評估過變更對專案的影響。因此，依據我們可以觀察到的事實來看，認為喲哪桑用感情衝動來管理專案，本來就是沒有根據的偏見。 個人信仰的偏見 既然沒有證據可以證明喲哪桑在未經事先評估的情形下，就逕行進行專案變更，那麼為什麼那位網友卻堅稱喲哪桑是用「感情衝動」來管理專案，並且說他並不適任專案經理的工作該離開呢？他提到每個人相信自己所相信的，本來就是人生信仰的一環。而他的信仰是「PM 不該因為個人情感的因素等非理智的理由，而貿然做出提升專案風險的決策」，因此根據這樣的信仰，他認為貿然接受了專案變更要求會增加專案的風險，這只是出於一時的感情衝動。 如果以上的理由是可以成立的，那麼一個人的確不應該用個人情感因素，來進行非理性的決策。但當我們真的這樣說時，我們卻忽略了這句話在邏輯上將會出現必然的謬誤；個人信仰本身也是出自個人情感因素，那麼為什麼別人的情感不理智，而我們的情感卻是理智了呢？ 這種出自個人信仰的偏見，正讓我想到在〈新官上任三把火〉與對不同軟體文化的情緒化貶抑正有著異曲同工之妙： 如果主導改革者的心態不是基於解決問題或客戶要求，而是基於自己情感的訴求，所謂的改革也只不過為了遂行其願的私心，卻讓專案與團隊成為無辜的陪葬品。 就像上述主導改革者的心態一樣，在專案面臨變更要求的時候，許多專案管理者會傾向用一己的偏好或私心來決定是否接受變更的要求。尤其是他們常會以開發資源不足或進度落後來當做理由，拒絕或延後專案變更的要求，以減輕他們的工作負擔。但如此一來，接受、拒絕或延後專案變更要求卻變成無法理性討論的議題，也很少人可以正視它們對專案所產生正面的助益或負面的影響。 專案風險的迷思 那麼這種無法正視專案變更要求的信仰從何而來呢？依據筆者對許多專案經理的觀察，我發現許多人會為了減輕對未來不確定的恐懼所產生的焦慮，以為不去正視專案變更要求就可以降低風險，但實際上卻反而對專案風險造成迷思。 當專案經理接受專案變更要求時，增加開發工作當然會影響專案時間表，這得確會為專案帶來一些風險。因為如果時間表的最後期限改變，會增加對完工時間與預算的不確定性或衝擊而造成風險、即使最後期限不改變，時間表的調整卻有可能造成要徑（其內的任務一旦延誤，就會影響專案完工日的工作）數增加的風險、或是為了趕工或因為作業重疊、省略品質流程等作業而產生重工率增加的風險等、這些都是接受專案變更可能帶來的風險。 既然接受專案變更要求會增加專案風險，那麼拒絕或延後專案變更要求是否意味著就不會增加風險了呢？當著眼點處於整個專案成敗的高度與視野時，我們將會發現答案是否定的。如同《專案管理之美學》提到的專案應該兼顧並協調各種觀點的平衡，這些觀點包括了技術面、客戶面與營運面。技術開發對於專案很重要，但除此之外，客戶需求與營運策略更是不可偏廢。 換句話說，因為技術觀點而拒絕或延後專案變更要求，很可能會影響客戶的滿意度或信任度、或是因為產品推出時效的問題而影響競爭力，這些風險的影響可能會比技術所造成的風險還來得嚴重而深遠的。 拿過去筆者曾經參與大型軟體專案的例子來說明，那是一個規模數億的政府部門的公共建設 BOT 計劃，包含了十幾個子專案。在各個專案設計開發告一段落的時候，筆者負責與業主及顧問商討該如何制定軟體程式設計規格的標準。 由於我們開發的系統很多，彼此又有相當的差異性，這使得我們在制定出一致性的標準的過程面臨相當大的挑戰。雖然這些問題很複雜，但整合起來其實並不困難，然而真正困難的地方是業主對我們的不信任，經常使得筆者藉著技術專業，很難說服他們可以接受我們的建議。 當時筆者就經常聽到業主對我說：「我當然瞭解你們提到的開發觀念，但問題卻發生在每次你們都說這個問題是什麼時候或什麼人會處理，但最後總是沒有人會處理這樣的問題」這總是令人無言以對，我們對客戶的要求經常拖延與事後相應不理，客戶當然也就學會了對峙之道。結果最後是誰吃虧呢？答案很明顯，即使他們的考績會因此受到影響，但對專案開發組織而言，專案一直遲遲無法驗收的結果，卻是讓我們損失慘重！ 應生無所住之心 既然拒絕接受改變的信仰會使我們因為無知，而處在專案風險的迷思當中，那麼身為專案經理對待專案變更要求，到底該不該「換了屁股，也要換了腦袋」呢？筆者認同其他人主張的「換了屁股，也要換了腦袋」說法，但卻想提出一個思考重點。 那就是不管專案經理決定要不要換腦袋，關鍵還是在於他面對問題的本質性思考。所以我認為對於專案經理而言，如何坐在他的位置上並不重要，重要的是他決定怎麼坐上位置之前的思考是什麼。 其實不同立場與觀點的衝突只是提昇其高度及視野的契機，專案經理應該好好利用這樣的機會，去反思為什麼換屁股，就必須換腦袋？或是如何換屁股而不換腦袋？想通了，就會讓自己的思慮變得更成熟而完整，使自己可以勇敢地面對無知而得到智慧。這也就是為什麼筆者會認為喲哪桑的作為令人激賞的主要原因，重點在面對自己的理性，而非對結論的情緒化反應。 筆者很喜歡用《金剛經》的「應生無所住之心」來類比專案管理的智慧，若專案經理太偏重於技術、客戶、業務任何一個觀點，都會造成執著而無法針對問題真相來進行思考，因為我們的心有所染著；但如果為了不去染著任何的觀點，無心讓自己變得冷漠卻也什麼事都做不成。換句話說，專案經理對專案展現熱情是必要的，它將會使得專案經理展現出慈悲與智慧的作為。 慈悲作為需要專案經理的情感，否則無從激勵專案團隊，也就很難產生出良好的專案績效。同時專案經理也必須搭配智慧作為，運用客觀評估與思考能力使得專案範疇、時間、成本等三重限制（triple constraint）能夠達到平衡。 總而言之，專案管理的智慧正是「若菩薩心住於法而行布施，如人入暗，則無所見；若菩薩心不住法而行布施，如人有目，日光明照，見種種色。」的道理，當人們偏執專案特定觀點時，專案問題對於當事者而言，也只是視而不見呀。]]></description>
			<content:encoded><![CDATA[<p>本篇文章是投稿 <a href="http://www.zdnet.com.tw/">ZDNet</a> 的文章原稿，並以〈<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20132278,00.htm">專案不確定導致焦慮與迷失</a>〉與〈<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20132294,00.htm">專案不確定性導致焦慮與迷失(下)</a>〉兩篇文章刊出。原稿未經 ZDNet 編輯，其內容可能會與刊登的文章內容有約略的不同。</p>
<p>專案經理常會面臨天人交戰的情境。當專案「<a href="http://www.lifeparty.idv.tw/blog/archives/282">計劃總是趕不上變化</a>，變化總是比不上老闆的一句話」之時，許多專案經理總是會擔心專案無法如期完成或害怕資源不足，而拒絕或延後專案變更的要求。但這樣的行為，卻往往造成工作成果無法符合專案實際需要的結構性因素，而使得專案的失敗機會大為增加。這對於具備智慧及膽識的專案經理而言，當然並不會樂見專案發生這樣的事情。</p>
<p>筆者前一陣子看到<a href="http://jonathanspeaking.blogspot.com">喲哪桑</a>在〈<a href="http://jonathanspeaking.blogspot.com/2008/07/blog-post_17.html">換了屁股，我也換了腦袋</a>〉的分享，提到他在時間緊迫的情形下，接受了專案的功能變更要求。那個變更要求原來是由他所提出，當時前任專案經理以時程緊迫為由而答應延後處理，而一直到他接任專案經理仍然還留在原處。但他認為他不能任由「行為造成結構」的情形發生，於是決定不要再讓這個專案變更要求再次拖延下去，並在當下對專案進行變更。</p>
<p>筆者認為喲哪桑的作為令人激賞，並且覺得那篇文章值得推薦。其原因並不是因為他針對專案變更做了什麼樣的決定，而是欣賞他在決策過程中，展現出面對自己的勇氣與解決問題的思考。不過，卻有其他讀者對那篇文章抱持相反的意見。</p>
<p>某位網友對喲哪桑的分享，批評他是靠感情衝動來管理專案，甚至用了「發瘋了你」、「不適任該離開的時候」等情緒性的字眼來指責喲哪桑的不是。他指出喲哪桑的文章所傳達的意念，實在有不可思議的謬誤，並且擔心那篇文章會透過 ZDNet 的報導，將不正確的知識與觀念誤導一般社會大眾。</p>
<p>然而，他對這篇文章的批評卻使人感到困惑，那位網友認為喲哪桑文章傳達的意念有不可思議的謬誤，但看在專業人士眼裡，這樣的觀點又何嘗不是相當嚴重的偏頗呢？筆者認為他的觀點傳達的意念本質上是一種面對不確定性的焦慮感，進而對改變的抗拒而產生無知的迷惘。</p>
<h4>專案變更的基本原則</h4>
<p>身為專案經理固然不應該因為個人一時的感情因素而使專案陷入危險之中，但在對專案缺乏可供客觀評論資訊的情況下，只憑專案經理接受專案變更的決定，就加以批判其決策感情衝動是否真的恰當？專案管理並不是神學或是玄學，而是屬於管理科學的範疇。因此，如果有人要批評某個專案經理是用感情衝動來管理專案，必須提出具體的事實根據，否則那只是無憑無據的推論而已，而這樣的推論多半只是源自於自我的偏見與扭曲。</p>
<p>以專案變更管理的原則來看，依據《<a href="http://en.wikipedia.org/wiki/PMBOK">PMBOK</a>》的說明，專案經理在管理專案變更的時候，必須注意三件事。首先他必須確定變更對專案的影響有其正面的價值；其次，他必須確認造成專案變更的因素已經發生；最後，他必須對變更加以管理。</p>
<p>從以上的原則我們可以發現，<strong>專案經理決定接不接受專案變更的要求，不應該源自於個人的主觀認定，而是必須經過客觀的評估。</strong>只有在蒐集了專案變更的各種相關資料，並加以評估之後，我們才能確知在專案現狀下，變更的正面效益或負面影響為何、到底值不值得立即採取行動來進行變更。而在未經評估之前，沒有人可以作出專案是否應該接受、拒絕或延後變更要求的決定。</p>
<p>喲哪桑的文章並沒有提到他所進行的專案變更並未經過事前的評估。相反地，他在對該位網友情緒漫罵性的言辭<a href="http://jonathanspeaking.blogspot.com/2008/08/tom.html">感到莫明其妙的文章</a>中提到，在部落格發表的文章中，他不能揭露太多工作細節，並且提到了在重提該項專案功能變更要求之前，提出者已經評估過變更對專案的影響。因此，依據我們可以觀察到的事實來看，認為喲哪桑用感情衝動來管理專案，本來就是沒有根據的偏見。</p>
<h4>個人信仰的偏見</h4>
<p>既然沒有證據可以證明喲哪桑在未經事先評估的情形下，就逕行進行專案變更，那麼為什麼那位網友卻堅稱喲哪桑是用「感情衝動」來管理專案，並且說他並不適任專案經理的工作該離開呢？他提到每個人相信自己所相信的，本來就是人生信仰的一環。而他的信仰是「PM 不該因為個人情感的因素等非理智的理由，而貿然做出提升專案風險的決策」，因此根據這樣的信仰，他認為貿然接受了專案變更要求會增加專案的風險，這只是出於一時的感情衝動。</p>
<p>如果以上的理由是可以成立的，那麼一個人的確不應該用個人情感因素，來進行非理性的決策。但當我們真的這樣說時，我們卻忽略了這句話在邏輯上將會出現必然的謬誤；個人信仰本身也是出自個人情感因素，那麼為什麼別人的情感不理智，而我們的情感卻是理智了呢？</p>
<p>這種出自個人信仰的偏見，正讓我想到在〈<a href="http://www.lifeparty.idv.tw/blog/archives/368">新官上任三把火</a>〉與對不同軟體文化的情緒化貶抑正有著異曲同工之妙：</p>
<blockquote><p>如果主導改革者的心態不是基於解決問題或客戶要求，而是基於自己情感的訴求，所謂的改革也只不過為了遂行其願的私心，卻讓專案與團隊成為無辜的陪葬品。</p></blockquote>
<p>就像上述主導改革者的心態一樣，在專案面臨變更要求的時候，許多專案管理者會傾向用一己的偏好或私心來決定是否接受變更的要求。尤其是他們常會以開發資源不足或進度落後來當做理由，拒絕或延後專案變更的要求，以減輕他們的工作負擔。但如此一來，<strong>接受、拒絕或延後專案變更要求卻變成無法理性討論的議題，也很少人可以正視它們對專案所產生正面的助益或負面的影響。<br />
</strong></p>
<h4>專案風險的迷思</h4>
<p>那麼這種無法正視專案變更要求的信仰從何而來呢？依據筆者對許多專案經理的觀察，我發現許多人會為了減輕對未來不確定的恐懼所產生的焦慮，以為不去正視專案變更要求就可以降低風險，但實際上卻反而對專案風險造成迷思。</p>
<p>當專案經理接受專案變更要求時，增加開發工作當然會影響專案時間表，這得確會為專案帶來一些風險。因為如果時間表的最後期限改變，會增加對完工時間與預算的不確定性或衝擊而造成風險、即使最後期限不改變，時間表的調整卻有可能造成要徑（其內的任務一旦延誤，就會影響專案完工日的工作）數增加的風險、或是為了趕工或因為作業重疊、省略品質流程等作業而產生重工率增加的風險等、這些都是接受專案變更可能帶來的風險。</p>
<p>既然接受專案變更要求會增加專案風險，那麼拒絕或延後專案變更要求是否意味著就不會增加風險了呢？當著眼點處於整個專案成敗的高度與視野時，我們將會發現答案是否定的。如同《<a href="http://www.anobii.com/books/0009244ebdbfe0a08a/" title="更多關於專案管理之美學">專案管理之美學</a>》提到的專案應該兼顧並協調各種觀點的平衡，這些觀點包括了技術面、客戶面與營運面。技術開發對於專案很重要，但除此之外，客戶需求與營運策略更是不可偏廢。</p>
<p>換句話說，<strong>因為技術觀點而拒絕或延後專案變更要求，很可能會影響客戶的滿意度或信任度、或是因為產品推出時效的問題而影響競爭力，這些風險的影響可能會比技術所造成的風險還來得嚴重而深遠的。</strong></p>
<p>拿過去筆者曾經參與大型軟體專案的例子來說明，那是一個規模數億的政府部門的公共建設 <a href="http://en.wikipedia.org/wiki/Build-Operate-Transfer">BOT</a> 計劃，包含了十幾個子專案。在各個專案設計開發告一段落的時候，筆者負責與業主及顧問商討該如何制定軟體程式設計規格的標準。</p>
<p>由於我們開發的系統很多，彼此又有相當的差異性，這使得我們在制定出一致性的標準的過程面臨相當大的挑戰。雖然這些問題很複雜，但整合起來其實並不困難，然而真正困難的地方是業主對我們的不信任，經常使得筆者藉著技術專業，很難說服他們可以接受我們的建議。</p>
<p>當時筆者就經常聽到業主對我說：「我當然瞭解你們提到的開發觀念，但問題卻發生在每次你們都說這個問題是什麼時候或什麼人會處理，但最後總是沒有人會處理這樣的問題」這總是令人無言以對，我們對客戶的要求經常拖延與事後相應不理，客戶當然也就學會了對峙之道。結果最後是誰吃虧呢？答案很明顯，即使他們的考績會因此受到影響，但對專案開發組織而言，專案一直遲遲無法驗收的結果，卻是讓我們損失慘重！</p>
<h4>應生無所住之心</h4>
<p>既然拒絕接受改變的信仰會使我們因為無知，而處在專案風險的迷思當中，那麼身為專案經理對待專案變更要求，到底該不該「換了屁股，也要換了腦袋」呢？筆者認同其他人主張的「<a href="http://prudentman.idv.tw/2008/07/blog-post_18.html">換了屁股，也要換了腦袋</a>」說法，但卻想提出一個思考重點。</p>
<p>那就是不管專案經理決定要不要換腦袋，關鍵還是在於他面對問題的本質性思考。所以我認為<strong>對於專案經理而言，如何坐在他的位置上並不重要，重要的是他決定怎麼坐上位置之前的思考是什麼。</strong></p>
<p>其實不同立場與觀點的衝突只是提昇其高度及視野的契機，專案經理應該好好利用這樣的機會，去反思為什麼換屁股，就必須換腦袋？或是如何換屁股而不換腦袋？想通了，就會讓自己的思慮變得更成熟而完整，使自己可以勇敢地面對無知而得到智慧。這也就是為什麼筆者會認為喲哪桑的作為令人激賞的主要原因，重點在面對自己的理性，而非對結論的情緒化反應。</p>
<p>筆者很喜歡用《金剛經》的「應生無所住之心」來類比專案管理的智慧，若專案經理太偏重於技術、客戶、業務任何一個觀點，都會造成執著而無法針對問題真相來進行思考，因為我們的心有所染著；但如果為了不去染著任何的觀點，無心讓自己變得冷漠卻也什麼事都做不成。換句話說，<strong>專案經理對專案展現熱情是必要的，它將會使得專案經理展現出慈悲與智慧的作為。</strong></p>
<p>慈悲作為需要專案經理的情感，否則無從激勵專案團隊，也就很難產生出良好的專案績效。同時專案經理也必須搭配智慧作為，運用客觀評估與思考能力使得<a href="http://en.wikipedia.org/wiki/Project_management#The_traditional_triple_constraints">專案範疇、時間、成本等三重限制</a>（triple constraint）能夠達到平衡。</p>
<p>總而言之，專案管理的智慧正是「若菩薩心住於法而行布施，如人入暗，則無所見；若菩薩心不住法而行布施，如人有目，日光明照，見種種色。」的道理，當人們偏執專案特定觀點時，專案問題對於當事者而言，也只是視而不見呀。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/391"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/391/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>專案時間不足，如何達成不可能的任務</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/321</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/321#comments</comments>
		<pubDate>Tue, 11 Mar 2008 08:54:20 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[CNet/ZDNet]]></category>
		<category><![CDATA[品質文化]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案規劃]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[開發流程]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/321</guid>
		<description><![CDATA[在專案時間不夠的情況下，要達成不可能的任務必須要提昇軟開發的產能，必須讓開發的產出與產能可以相互配合。但至於要如何增進良好設計架構的產能呢？]]></description>
			<content:encoded><![CDATA[<p>本文係投稿於 <a href="http://taiwan.cnet.com">CNet</a> / <a href="http://www.zdnet.com.tw">ZDNet Taiwan</a> 的初稿，並分為<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20127698,00.htm">上</a><a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20127699,00.htm">下</a>兩篇文章刊出，未經 ZDNet Taiwan 編輯，其內容可能會略有差異。</p>
<p>軟體專案開發常常會面臨時間不足的問題，尤其在台灣，Price on Cost更是不容易達到的理想，迫於現實，開發者只能硬著頭皮上陣去執行不可能的任務。但最後的結果卻常常是賠了夫人又折兵。即使透過不斷地加班，任務依舊還是無法完成，而且還會造成團隊士氣低彌，使得開發者缺乏工作的成就感與滿意度，甚至使專案開發人力大量流失。</p>
<p>其實大多的軟體開發者都期望專案能爭取到足夠的開發時間，不希望他們的青春浪費在無意義且永無休止的加班上。然而，軟體開發的現實就是如此殘酷，受到開發組織的營運面影響，通常專案總是很難爭取到足夠而充裕的開發時間。專案常會受限於市場競爭壓力的考量，為了爭取專案的機會常常會不得不遷就營運觀點而放棄工程與技術的堅持，因而使得專案無法爭取到合理的開發時間。</p>
<h4>工程與技術的妥協</h4>
<p>在台灣，軟體的定價通常是由市場供需機制所決定的，而不見得可以考量到軟體開發的成本。當市場競爭愈激烈時，軟體的價格就相對地會降低。開發者為了獲利，於是就必須想辦法降低開發成本，才能獲取相當的利潤，於是軟體的品質就會受到影響，因為軟體價格實在太低了，開發者只好捨棄一些可以增進或維持軟體品質的作業。結果軟體品質就會變成時間允許才能夠達到的一個理想，而現實通常是「時間總是不夠」。</p>
<p>當軟體專案把軟體價格當做專案成本估算的基礎時，這樣軟體開發就會<a href="http://www.lifeparty.idv.tw/blog/archives/150">沒辦法重視專業</a>，只能讓外行（市場因素）領導內行（研發設計專業），軟體開發者的痛苦夢魘於是從此開始。</p>
<p>所以，Price on Cost 的理想是很難達到的，現實就是這樣，專案就是難以爭取到足夠的充裕時間。但這樣要如何才能達到專案不可能的任務呢？從筆者在工作上的觀察中發現，不少的管理者會將這個問題焦點放在團隊生產力上，以提昇軟體的開發效率來縮短開發時間。不過，實際上卻不見軟體開發成果獲得到顯著地提昇。</p>
<h4>生產力的迷思</h4>
<p>通常，管理者會希望軟體開發者加班或是增派開發人力，來提昇軟體開發的生產力。軟體開發每日的總工時增加了，照理說應該是可以增加軟體開發的效率，但卻也因此引發出新的問題，也就是軟體開發出錯的機率也會隨每日工作時數或開發人力增加而增加，反而降低了軟體開發的效能。</p>
<p>為什麼會這樣呢？綜歸一句話，<u>增加了生產力卻讓軟體開發變得更複雜</u>，使得團隊無法有效整合、發揮綜效。而這種現象又可從兩個方面來看，一方面是加班讓開發者身心耗弱、無法集中心力來完成任務，因此常因為工作上的疏忽而產生錯誤，反而讓問題變得更複雜，需要花更大的心力才能解決。另一方面則是團隊規模變大，人與人之間需要更多的溝通時間與成本來整合工作成果，因此每個人的工作量不減反增，同時又有意見分歧可能引發團隊衝突影響專案績效的風險。</p>
<p>理論上，壓縮專案時程可以運用趕工（crash）或作業重疊（fast tracking）的方式來減少開發時間。趕工必須讓工作者加班而增加開發成本，作業重疊則會增加工作產出重工（rework）的風險。因此，似乎只要多付一些成本來支應加班的需求或加強風險管理，應該就可以達到時程壓縮的目標。然而，由前面的分析我們卻可以發現到，軟體開發的複雜度其實是經常超乎我們想像的，由此可知，<strong>軟體專案的時程上的妥協其實是很難用成本來彌補的</strong>。</p>
<p>筆者最近才聽到朋友告訴我一個軟體專案失敗的案例，該專案是以另一個將近結案的專案為基礎。原來他評估勉強半年可以完成，本來公司把專案交由他負責，但最後專案經理卻因為客戶的意見而交由負責該客戶的業務來掛名，實際上專案則由我的朋友來負責開發該專案。</p>
<p>然而，當我的朋友才開始需求訪談時，專案經理卻告訴我的朋友他程式開發時間要在三個月內完成。而在我的朋友在研讀前一個專案的程式碼，以求了解程式架構以後才能根據客戶需求加以修改，那位專案經理卻要我的朋友立刻著手動手修改程式，問題留待後面再來處理。</p>
<p>雖然我的朋友還是在時限內完成了程式，不過，這時候問題才真正開始。客戶驗收後提出了上百個程式錯誤。這時候我的朋友才發現，這專案所依據的快結案的專案本身就有很多問題，並不是像那位專案經理所說的「沒有問題」，因為有 3/4 的 bug 都是那個專案本來就存在的問題。</p>
<p>此外，客戶還提出了一些原先沒談到的需求，而那位專案經理則要求我的朋友要在不增加時間的情況下予以照單全收。因此在需求不斷膨脹的情況下，這個專案最後還是失敗了。當然，最後那位專案經理把失敗的所有責任都推到我的朋友身上。</p>
<p>相信任何有經驗的軟體開發者看到這故事都會了解，那個專案經理實在是太外行了，他以為軟體開發只是依據客戶的需要來產出程式，認為只要壓縮開發者的時間來產出更多的程式就可以解決問題。卻殊不知<strong>軟體開發在缺乏產能的情況下，再多的產出也只是徒增軟體的複雜度與風險</strong>，這樣要成功地達到專案目標只能靠聽天由命了。</p>
<h4>開發產出與產能之平衡</h4>
<p>由此可知，在專案開發時間不足的情況下，用生產力的迷思所生產的程式產出，其實多半是無法具有實質效用的。因為開發者在龐大時間壓力是很難會有思考的空間，將使他的產能逐漸耗竭殆盡。即使在剛開始，可以一時滿足了客戶的需要，然而長久下來，卻在無形之中增加了專案的複雜度，最終只會在耗盡了開發者的青春與熱情之後，得到專案失敗的苦果。</p>
<p>因此，在專案時間不夠的情況下，要達成不可能的任務必須要提昇軟開發的產能，必須讓開發的產出與產能可以相互配合。但至於要如何增進良好設計架構的產能呢？依筆者在軟體專案開發的實務經驗來看，關鍵在於必須同時兼顧<strong>客戶價值</strong>與<strong>開發風險</strong>。而要做到這一點則必須要讓開發者與客戶<strong>充分溝通</strong>，讓專案產出確實可以為客戶創造最大的價值，同時也能有效地降低專案的風險。</p>
<p>筆者常觀察到許多開發者習慣把客戶提出來的功能直接當做軟體需求規格，卻沒有深入分析客戶真正遇到的問題。他們以為問題領域、業務流程或現場作業等知識是客戶的專業，開發者無從介入，因此往往在不知客戶要求之所以然的情況下，直接把客戶的話轉換成軟體規格。</p>
<p>然而，客戶所知道的並不是軟體需求（requirements），他們對系統的觀點只能顯露出他們對系統的需要（needs）。需要是抽象而片斷的，本身是非結構化的，而可用的軟體需求卻必須是具體而完整一致的，具備結構化的特性。</p>
<p>因此，如果開發者沒有針對客戶需要分析他們的問題，設計解決方案，只是直接把客戶的想法直接轉成軟體規格的話，客戶心中想的那朵雲，隨時都會變幻出各種不同的形狀，需求不斷變動當然是必然的，<strong>如果開發者沒做適切的分析及設計，只靠技術是很難滿足客戶多變的渴望與需要的</strong>。</p>
<p>事實上，軟體開發是知識與腦力密集的工作。自許為知識工作者，重要的不在於產出的數量，而在產出的品質。要讓產出具有足夠的水準，必須要有足夠的時間在<strong>問題領域的分析</strong>上，才可能為客戶設計出可以解決他們問題的軟體，為客戶創造價值；也才能讓軟體具備足夠的彈性來適應客戶千變萬化的需求，有效地降低開發風險。</p>
<h4>要如何充分溝通？</h4>
<p>於是，當我們用以上的思路來看軟體開發時，<strong>縱使專案沒有足夠的開發時間，我們依然要會從客戶的立基點中去思考問題</strong>，並從中找出最可行的技術來創造客戶的最大價值。同時，在這樣的情況下，開發者展現了足夠的專業，客戶也會很自然地信任開發者誠意與專業，形成了良性的雙向溝通。</p>
<p>在這種客戶與開發者良性溝通的情況下，客戶可以決定了時程、成本、品質等限制條件，而<strong>專案範疇的限制條件則應該由開發者與客戶溝通後依業務需求及技術架構的取捨來決定</strong>。這也就是說，客戶提出他的問題、以及希望解決的時限及願意付出的成本。開發者則應該針對問題分析出需求規格、發展出技術架構，並據此實作出軟體後再交由客戶驗收。然後客戶再依軟體實際使用狀況予以回饋，開發者再依照客戶的意見反覆地演化系統，以使軟體更趨於完善。</p>
<p>客戶應該優先提出<strong>最關鍵及最核心的業務問題</strong>，而開發者則必須針對這些問題分析，發展出軟體需求、找出解決問題應採用的技術與方法、優先將<strong>最高風險及最核心的架構與程式</strong>實作出來。<strong>如此客戶最重要的問題可以優先被解決，而開發者也可以針對客戶問題而設計，而不會浪費時間與成本在過度設計上</strong>，降低了軟體開發的風險與複雜性，使得產出與產能可以相互配合。</p>
<p>開發產出與產能相互平衡，才不會偏廢於需求面或技術面，使技術可以面對現實地解決客戶的問題。就算開發時間真的不夠，至少也可以用空間換取時間呀。因為無論如何，客戶至少都會擁有一個可用的系統，而不是一堆無法正常運行的程式碼與文件。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/321"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/321/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>總是要到驗收前才發現程式有問題？</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/308</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/308#comments</comments>
		<pubDate>Mon, 04 Feb 2008 01:28:04 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[CNet/ZDNet]]></category>
		<category><![CDATA[品質文化]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[專案團隊]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[思考]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[職場]]></category>
		<category><![CDATA[軟體審查]]></category>
		<category><![CDATA[開發流程]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/308</guid>
		<description><![CDATA[對於開發者而言，總是要到驗收前才發現程式有問題可真是可怕的夢魘呀。然而，這樣的現象為什麼老是一而再，再而三地發生，到底是什麼地方出了問題呢？]]></description>
			<content:encoded><![CDATA[<p>本文係投稿於 <a href="http://taiwan.cnet.com">CNet</a> / <a href="http://www.zdnet.com.tw">ZDNet Taiwan</a> 的初稿，並分為<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20127026,00.htm" target="_blank">上</a><a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20127031,00.htm" target="_blank">下</a>兩篇文章刊出，未經 ZDNet Taiwan 編輯，其內容可能會略有差異。</p>
<p>軟體專案團隊在專案開發的過程中，常會面臨許多問題，例如需求的不斷變化、資源的短缺、時間的急迫性、以及技術的難以掌握等。這些事件雖然都將直接影響專案的產出與品質，並且會令開發者會感到相當困擾，但只要存在希望，問題都還是可以有解決之道的。然而，在什麼情況下，專案發生了什麼事會讓開發者完全失去希望，並且感到他的世界相當悲慘呢？</p>
<p>相信許多人都會同意，總要等到專案驗收前，才發現程式品質有問題是一件很令人沮喪的事情。而筆者根據軟體專案實務經驗也發現，對軟體開發者而言，最悲慘的事件莫過於在專案臨驗收之際，才發現程式沒有合乎品質上要求。</p>
<h4>軟體開發者的悲慘世界</h4>
<p>筆者用一個笑話來比喻這種開發者的悲慘世界。話說有三兄弟開車回家，就在車停妥在停車場時，突然發現大樓停電了。很不巧的是，他們住在五十樓，停電沒辦法坐電梯，於是他們只能用爬樓梯的方式回到他們居住的地方。</p>
<p>爬到十樓的時候，大哥建議每人講一個最悲慘的故事，並且從他開始。大哥說：「從前有一個人從小就沒有父親，是由母親含辛茹苦地養大，好不容易稍稍有了一點小成就想要報答母親時，母親卻病死了。」，說完時他們己經到了二十樓。</p>
<p>二哥接著說：「從前有一對情侶非常相愛，男孩要出國留學，女孩也發誓不管多久一定會等他回來，四年之後男孩終於學成歸國，女孩也堅貞如是，但是女孩卻在去接他的途中出車禍，當場死亡。」講到這裡時，不知不覺的已經到了四十樓。</p>
<p>這個時候，沒想到三弟只不過說了一句話，三兄弟馬上坐在樓梯上大哭。他說：「大哥，二哥，對不起，我忘了把鑰匙放在車上了！」</p>
<p>軟體開發者的悲慘世界就像這個笑話一樣，眼看目標就在眼前，這時卻發現最關鍵的地方，亦即軟體品質沒有達到要求而將導致前功盡棄。而更令人絕望的是，在最後一刻才發現這樣的窘境，此時要及時彌補缺失卻是相當困難的。</p>
<p>就像笑話中的三兄弟一樣，他們必須有人回車上拿鑰匙，而原來走過的路要再重新再走一次。軟體專案開發也是一樣，<strong>先前沒做好的開發作業必須回過頭重新把它們做好，而後續的開發作業也必須重做一次。但問題是客戶馬上就要驗收，開發者通常已經沒有足夠的時間來解決問題了</strong>。</p>
<p>對於開發者而言，這樣的悲慘世界可真是可怕的夢魘呀。然而，這樣的現象為什麼老是一而再，再而三地發生，到底是什麼地方出了問題呢？顯然<strong>問題多半出在開發者無法儘早發現程式瑕疵並及時因應，卻讓自己在茫然無知的狀況下，讓問題不斷地惡化下去</strong>。而依據筆者的實務經驗顯示，這種現象可以從<u>開發者的紀律</u>、<u>確認與驗證的過程</u>兩方面來理解。</p>
<h4>開發者的紀律</h4>
<p>可能有些人會把無法早期發現程式瑕疵歸咎於「無常」兩字，就像笑話中大哥、二哥所提供的故事一樣。得確，軟體專案的本質是充滿不確定性的，實際上會發生的問題是很難事先預料得到的。然而，但當我們經過深入地去檢討後卻常常可以發現，<strong>藉由良好的開發者紀律可以減少因為一時疏忽而產生不良後果</strong>。就如同笑話中三弟所言的疏忽一樣，<strong>許多程式的瑕疵是因此在剛開始分析或設計時就己經存在了需求或設計規格中</strong>，但卻直到最後一刻才會被發現。</p>
<p>依據筆者的觀察，一些軟體開發者在分析或設計時，經常不會事先思考需求或設計規格的驗證問題，而是等到程式實作出來過後才會開始思考測試該如何進行。由於在需求或設計規格上，並沒有思考到如何驗證的問題，其內容就常常就會因為不夠完備而顯得草率而馬虎，自然使得程式碼的產出常常會缺東漏西，甚至產生一些錯誤。</p>
<p>而等到開發者在開始進行編程時，規格上所缺漏的部分自然就不會被實作出來，而需求與設計的錯誤更會具體地被實作在程式碼當中。當然部分需求或設計的疏漏與錯誤，可藉由在實作的過程中被發現。但對於一些經驗、能力不足、或態度不夠積極的程式實作人員而言，他們通常只會按照規格來開發程式，而不會去進行溝通並發展良好的程式結構來解決工作上的問題。</p>
<p>另外，有些開發者會習慣於暫緩程式的驗證，他們總以為進行程式的開發遠比進行測試驗證還來得要有生產力，甚至在面對時程的壓力時，會選擇<a href="http://www.lifeparty.idv.tw/blog/archives/201">省略功能測試</a>，期望以整合測試或系統測試來將測試問題延後處理。</p>
<p>因此，以上種種原因，使得<strong>測試作業太慢開始、程式碼之中散佈著因為需求或設計規格、或實作結構問題所產生的一些疏漏或錯誤，這些現象使得程式瑕疵擴散或蔓延的速度比修正的速度還來得快</strong>。當程式的瑕疵愈變愈多、除錯就會顯得更困難，對程式的除錯與測試都是個沉重的負擔，更不用說可以及早發現程式中的瑕疵了。</p>
<h4>確認與驗證的過程</h4>
<p>在<a href="http://en.wikipedia.org/wiki/Software_engineering">軟體工程</a>的領域中，確認過程代表確定開發產出滿足及符合原始的設計，也就是把事情做對。而驗證過程則代表檢查開發設計滿足或適合預期的使用，也就是做正確的事情。在台灣，一般大型軟體專案多半採用 V-Model 的軟體開發流程模式來進行軟體的<a href="http://en.wikipedia.org/wiki/Verification_and_Validation_%28software%29">確認與驗證</a>。此開發模式展現了不同抽象層次觀點的開發作業與相關的測試作業之間的關係。</p>
<p>一般而言，我們會將軟體專案開發分為三個開發層次，高階的抽象層次為處理使用者的需求分析；中階的抽象層次則將重點置於將所了解的需求轉化為軟體架構；低階的抽象層次主要為系統功能的細部設計與系統實作。</p>
<p>在每個開發作業完成之後，開發者應當進行確認過程來確保開發作業符合需求及設計規格後才能進行下一個開發作業。而直到程式被實作出來之後，開發者必須依序按照不同開發層次的要求來進行驗證過程，以各種不同類型的測試作業來檢查軟體是否真能符合實際使用上的需求。如下圖所示。</p>
<p><img src="http://www.lifeparty.idv.tw/blog/wp-content/uploads/2008/02/vmodel.PNG" alt="vmodel.PNG" /></p>
<p>此開發模式配置了良好的結構方法，讓每個開發作業都可以根據前一個開發作業的詳盡產出來進行作業。而測試計劃可以很好地提早在編程前就開始進行規劃，如此將為專案省下大量的時間。但事實上，<strong>採用 V-Model 在專案後期仍然還是會從程式碼當中出現不少瑕疵，似乎按照規格來開發系統仍然無法解決需求與設計在專案後期因為經常變動而影響程式碼品質的困境</strong>。</p>
<p>為什麼會如此呢？從 V-Model 的開發流程結構我們其實不難發現到，<strong>愈高階層次的開發作業是愈晚被驗證的，而在它尚未被驗證前，較低階層次的開發作業都會因為它的變動而受到影響</strong>。例如，在系統測試時，如果發現軟體無法通過驗證的原因是因為需求規格的瑕疵，如此就必須回過頭來修正需求規格的瑕疵，並重新進行設計與程式開發。</p>
<p>換句話說，愈高階層次的開發產出，其瑕疵是愈晚才會被驗證出來。而相較於低階層次的開發產出，其衝擊影響力又是相當嚴重的，因為這代表瑕疵將會在較低層次的開發產出中擴散與蔓延。因此在實務上要做到「<a href="http://jonathanspeaking.blogspot.com/2007/03/blog-post_07.html">早期發現、早期治療</a>」，讓需求或設計的瑕疵盡早被發現與解決其實並不容易。除非需求與設計規格能夠儘早驗證完全無誤，然而，在程式在尚未實作出來之前，開發者又該如何做到這一點呢？</p>
<h4>如何早期發現、早期治療？</h4>
<p>如果對於需求或設計，開發者無法先驗證其可行性與正確性，而必須等待程式實作出來才能靠測試作業來加以驗證的話，那麼我們將會<strong>期望測試作業必須具備相當高的效率及足夠的涵蓋面</strong>。但實際上，測試的效率與涵蓋面會受限於專案的時程與成本，因此希冀測試作業能夠有效率地找出程式所有的瑕疵的想法往往是不切實際的。</p>
<p>一旦我們愈晚進行測試，因未驗證的分析設計而產生的遺漏或缺陷將會使程式中的缺陷不斷地擴散，如此將會使開發人員更窮於應付。換句話說，不良的需求或設計往往會加重測試的負擔與壓力。</p>
<p>因此，要用較低的成本與時間來達到最佳的程式品質，其關鍵並不在於測試的效率與涵蓋面，而是在於<strong>提昇需求與設計規格的品質</strong>。然而，我們該如何發展出較佳的需求與設計規格，並且能夠及早發現存在需求與設計規格的瑕疵以適時加以修正呢？</p>
<p>筆者認為，開發者在進行分析及設計的過程中，就應該<strong>同時思考需求規格與設計該如何驗證</strong>的問題，而不是等需求或設計規格完成後才去設計驗證的程序。同時，在需求或設計規格交付之前，應該<strong>讓團隊針對欲交付產出進行實質上的技術審查</strong>，以集思廣義的方式促進集體反思，以找出分析或設計者所忽略的潛在問題與瑕疵。</p>
<p>如此將使因個人盲點而產生之需求或設計的瑕疵會因此大幅減少。因為，為了要找出如何驗證需求或設計規格的方法，就會強迫我們客觀思考自己的想法是否完備、有沒有被我們所忽略的問題沒被考慮到，進而完善我們的思慮。另一方面，請別人來一齊檢查自己所分析或設計的開發產出，更可以站在更客觀的立場來看問題，透過不同的觀點來了解自己是否忽略了什麼。透過集體思考的過程，我們可以得到更為一致的需求與設計觀點，就不會流於個人的執著與徧頗。</p>
<p>在驗證需求或設計方面，在分析或設計過程就必須思考驗證需求或設計的具體方法。這代表了不一定要等實作設計的程式完成後，才能開始寫測試程式。<strong>如果我們無法依據設計來寫出測試程式時，其實正代表著我們設計的思慮多半是有問題的，我們對設計的想法可能還不夠具體，如此的設計是很可能存在許多我們所想不到的缺陷與瑕疵的</strong>。當然，先寫測試程式並不是唯一可以「在分析或設計過程中思考需求或設計如何驗證」的方式，不管採用任何形式的開發方法論，筆者認為都應該先想到如何以具體可行的方式來驗證需求與設計。</p>
<p>舉個例子來說，架構設計必須包含架構的概念驗證（POC，Proof of Concept）。架構設計者不應該省略驗證架構的程式，卻期待程式實作者來幫他實現未經驗證的設計構想。他必須自己親自驗證架構，如此才能透過驗證，<a href="http://www.lifeparty.idv.tw/blog/archives/163">使自己設計的架構趨於成熟</a>，而不致讓開發團隊在使用架構的過程中出現問題叢生的困擾。</p>
<p>而在技術審查方面，在設計過程中進行 software inspection，除了可以提早發現需求或設計的瑕疵，更能促進團隊成員相互學習以提昇開發能力。品質不只要靠檢驗，而是不去設計有缺陷及瑕疵的系統。然而，不管開發者的分析或設計能力有多強，都不能保證其開發產出絕對沒有問題。在這種思維下，全員參與是一個好主意，於是<strong>讓同僚參與需求或設計規格的審查可讓系統設計更趨於完善，一來可以用比較客觀的方式來確保設計符合需求及使用者需要，二來也可以讓同僚更清楚我們在做什麼，相互觀摩學習並增進團隊的效能</strong>。</p>
<p>因此，在思考如何驗證需求與設計的過程中，會讓我們不知不覺地把焦點放在最主要目標的達成上，可以讓我們更有效地整合開發作業與測試作業。而讓同僚參與分析與設計的討論過程中，將有效撤除開發作業之間的藩離，透過同步的協同作業可得到截長補短的好處，如此將發揮一加一大於二的團隊綜效。其實<strong>同步與整合，正是讓程式瑕疵得以早期發現、早期治療的有效的做法呀</strong>。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/308"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/308/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>好的變更來自於可行計劃</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/285</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/285#comments</comments>
		<pubDate>Thu, 27 Dec 2007 09:23:32 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[問題解決]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案規劃]]></category>
		<category><![CDATA[專案風險]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/285</guid>
		<description><![CDATA[人們總是習慣高估了自己的能力，低估了風險。因此，在做出自認為臨機應變的取捨之前，不妨先想一想，我們憑什麼認為這次的變更是個好變更？]]></description>
			<content:encoded><![CDATA[<p>軟體專案後期的變更會讓團隊無法按照既定計劃進行，然而因應現實需求變更又勢在必行時，我們又該如何取捨呢？學長<a href="http://jonathanspeaking.blogspot.com">喲哪桑</a>在〈<a href="http://jonathanspeaking.blogspot.com/2007/12/late-changes-can-be-good.html">Late Changes Can Be Good</a>〉提出我們必須認清專案初期的需求規格永遠是不完整的事實，因此好的經理面對專案後期變更應該要懂得取捨，發展出良好的適應變更的機制。他提到：</p>
<blockquote><p>大家都不喜歡 Late Changes，我也不例外。不過，也不要有受害者的心態，把 Change 當做誰的疏失、誰的錯誤、是誰害的。我們還是得認清事實，就是專案初始時的需求規格永遠是不完整的。</p>
<p>好的機制，是要讓產品專案能夠快速應變，而同時間又能把品質的傷害、生產力的影響降到最低。</p>
<p>好的 manager，要懂得取捨。Late Changes Can Be Good.</p></blockquote>
<p>學長所提的觀念其實並不難理解，但依據同人實務上的觀察卻發現，在面對壓力時，專案管理者往往無法做適當的取捨。理想上，大家都會以為加一點東西、做一點小改變，程式應該不會有什麼問題才對。但事實往往是「千金難買早知道，萬般無奈想不到」，改變對軟體品質的傷害、生產力的影響總是超乎我們的想像，更可怕的是變更所造成的災難似乎永無止盡。當初取捨時的樂觀，事後我們才會發現那其實是無知。</p>
<p>就拿同人在〈<a href="http://www.lifeparty.idv.tw/blog/archives/252">沒有說出來的衝突</a>〉中所提到的故事為例。某個專案在面臨即將驗收之際，一些開發者因為專案的壓力而不遵守修改紀律時，該專案的管理者以為應該不會發生太大問題也沒有予以糾正，但結果卻讓專案失去了控制。經歷過這次經驗及教訓，他分享了他的體會：以放縱不遵守紀律來因應變動需求其實是不智之舉。而從他的經驗我們不難發現到，人們總是習慣高估了自己的能力，低估了風險。因此，在做出自認為臨機應變的取捨之前，不妨先想一想，我們憑什麼認為這次的變更是個好變更？</p>
<p>理論上，依據《<a href="http://en.wikipedia.org/wiki/Project_Management_Body_of_Knowledge">專案管理知識體系指南</a>》（PMBOK）的指引，我們可以找到在專案的範疇、成本、以及時間變動管理必須注意的共通要點，以確保專案在變更過程中能夠確實因應實際變化，包括了：</p>
<ol>
<li>確認變更對專案有正面的影響。</li>
<li>確認造成變更的因素已經發生。</li>
<li>管理變更。</li>
</ol>
<p>這也就是說，好的變更必須反應專案實際現況、並對專案有實際助益、同時必須要是可管理的。因此，如果只是想到什麼就做什麼並不是好的變更。因為那代表我們對專案變更的想法只是停留在觀念階段，我們必須找到客觀資料來證明它是可行的，然後再進一步地發展出具體可實踐的方法。否則專案將充滿著許多未知的不確定性，將很容易讓專案陷入危難之中。</p>
<p>《孫子兵法》說：「多算勝，少算不勝，而況無算乎！吾以此觀之，勝負見矣。」如果我們發現了變更會帶給專案實際助益，更需要週全的可行計劃來確認它是可以被實現，這才是專案的致勝之道呀。然而，具體做法又是如何呢？同人認為必須客觀而穩定地觀察專案現況，並依據客觀資料來分析變更將對專案所造成的影響。然後再進一步因應實際問題來調整計劃，以做採取行動的有效控制基準。</p>
<p>因此，不須把問題推到<a href="http://blogsearch.google.com/blogsearch?hl=zh-TW&amp;tab=mb&amp;q=%E6%94%B6%E5%B0%BE%E5%B7%B4&amp;btnG=%E6%90%9C%E5%B0%8B%E7%B6%B2%E8%AA%8C">收尾巴</a>過程才來解決，也不用在此黑暗時期讓無窮無盡的壓力來讓我們喘不過氣。只有在當我們懂得面對變化不斷地對計劃進行調整時，這才是真正的認清事實。</p>
<p>「菩薩畏因，眾生畏果」，變動所造成品質的傷害、生產效率的低落的苦果往往是因為我們太重視執行結果，卻忽略了規劃與控制的過程。如果我們不懂得專注於過程中，把注意力放在因應變化來進行可行計劃的調整上，我們將很難判斷這次的變更結果是否會造成下次變更原因。過程對了，結果自然就不會錯。雖然 Late Changes Can Be Good，但好的變更也必須是來自於可行計劃呀。</p>
<p class="poweredbyperformancing">Powered by <a href="http://scribefire.com/">ScribeFire</a>.</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/285"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/285/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>軟體開發者不應該自廢武功!!</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/262</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/262#comments</comments>
		<pubDate>Mon, 12 Nov 2007 03:20:25 +0000</pubDate>
		<dc:creator>jim yeh</dc:creator>
				<category><![CDATA[CNet/ZDNet]]></category>
		<category><![CDATA[分析設計建模]]></category>
		<category><![CDATA[問題解決]]></category>
		<category><![CDATA[專案監控]]></category>
		<category><![CDATA[專案風險]]></category>
		<category><![CDATA[溝通]]></category>
		<category><![CDATA[系統思考]]></category>
		<category><![CDATA[設計原則]]></category>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/262</guid>
		<description><![CDATA[本文係投稿於 CNet / ZDNet Taiwan 的初稿，並分為上下兩篇文章刊出，未經 ZDNet Taiwan 編輯，其內容可能會略有差異。 如眾所週知的，軟體開發專案具有高度不確定的特質。因此，為了降低需求變動的風險，在專案初期，軟體開發者往往會花費許多的心思，設計出具有彈性的軟體架構以適應未來可能的需求變化。大部分的開發者都了解軟體需求是不可能不改變的，但他們希望不管軟體需求如何變化，軟體開發的設計概念都不會因此受到影響或改變，如果可以做到這一點，軟體開發就會變得比較有效率，同時也能確保所開發之軟體的品質。 然而，現實總是和理想存在著一些落差的，專案的演變往往會超乎開發者事先的預期。尤其是當專案的驗收日期愈來愈接近時，專案可運用的資源也會愈來愈少，專案或許已不如剛開始時充滿了未知與不確定性，但相對地，專案的可變動性也愈來愈小。因此，在專案後期出現專案問題，或是需求的變動，相較於相同專案問題或需求變動在專案初期出現而言，會顯露出更為嚴重的危機與壓力的。 每個人都希望寧願事前多做一些風險管理，勝過事後的危機處理，而且後者的壓力是很容易讓做錯事的。然而，軟體易變的特質及專案環境的不確定性讓人難以捉摸，更不用說預測變化了，卻只能在事後才徒然留下「千金難買早知道，萬金難買後悔藥」的感嘆。但問題還是要解決的，到底軟體開發者在遇到這種危機時該如何處理呢？ 軟體品質的問題 我們是否能拒絕變動？或許凍結需求，拒絕變動可以讓軟體開發成功，但這樣的做法卻不會讓專案成功。因為軟體專案如果無法符合軟體需求者的需求，專案並不能算成功，以軟體需求者的立場而言，客戶永遠是對的，他們並不在意技術有何難處，但卻會很關心軟體能否幫他們解決問題。所以，如果開發者所開發出來的軟體不能符合他們的需要、為他們創造出價值，軟體需求者會認為軟體品質並未達到目標，未符合品質目標，專案當然不能算是成功的。 如果變動無法拒絕，那麼只好接受它了，但這對軟體開發者而言，往往是重大挑戰。根據筆者參與軟體專案開發的實務經驗顯示，因為需求變更的原因，要向客戶去爭取專案合理的時程及增加開發成本其實並不容易。所以在專案時程與成本無法變動的情況下，想要解決專案的問題與滿足使用者的需求，很容易因此影響到產出軟體的品質。 其實從專案管理的三重限制（triple constrainst）的觀念應不難瞭解到軟體品質與專案時程、成本及軟體需求之間常會相互影響，因此，當專案時程及成本無法變動時，我們很容易可以理解軟體需求的變動將會影響到軟體品質。 而在實務上，軟體開發專案常會時程壓力、專案得到的支援與資源不足等原因，使開發者沒有足夠的動機、時間、與精力來分析問題以設計合理的解決方案，取而代之則是直接修改程式，以符合軟體需求者所提出的功能，就算發現了因此將會破壞了設計上的結構也在所不惜。就短期而言，在設計的結構上做一些犧牲，雖然如此可以換取增加軟體需求者所提出功能的空間。但長期下來，缺少對問題分析與完整設計的系統，自然而然會衍生出許多軟體品質的問題。 解決問題的洞見觀瞻 如此看來，軟體專案的需求變更，常會造成開發者的左右為難。計劃趕不上變化，現實就是變化無常的，所以藉由預測與控制要變動不會發生是不切實際的。但擁抱改變似乎沒有想像中的那麼單純，隨著需求的變化無常，程式碼也愈來愈複雜，造成更高的軟體出錯的機率，增添程式碼維護的困難度。 情況真的無法改變嗎？那也不見得，筆者認為想要脫離這種兩難的困境，開發者應先具有洞見觀瞻，認清軟體開發者應該面對現實，但應該避免因為捨本逐末的行為模式而形成自廢武功的後果。 如圖所示，表面上，忽略設計的行為雖然可以省下時間來修改程式，以解決眼前的專案壓力，但因為環境仍舊不斷地在變化，所以開發者忽略設計的狀況會一直持續地發生，才能節省更多的時間來對變化做出回應。然而，長久的忽略設計，卻會影響軟體設計的概念完整性，結果將會產生軟體設計結構不良的後遺症，專案壓力最後當然會不減反增了。 當開發者長期地忽略設計，他就不會花心思在軟體的概念性設計上，更不用說提昇軟體設計的抽象化思維的能力了。換句話說，開發者只能憑藉軟體實作的技巧來解決問題，但這是很危險的，因為這樣程式碼只會愈改愈複雜，變得難以令人理解，同時溝通起來也會變得格外困難，出錯機會也就增加了，造成更多的專案壓力。 另一方面，長期忽略設計，設計的概念不夠完整，也就是設計會遺漏一些重要資料，因此設計無法重覆地被運用，而實作上又充斥了許多的特例，存在許多的資料細節，因此要重覆使用也會有困難。也就是說，軟體的設計缺乏完整及一致性，其實作又與業務邏輯之間產生複雜的相依性，因而軟體各元件其實缺乏再用性與彈性。用軟體開發領域中常聽到的話來說，就是開發者要不斷地重覆「造輪子」，軟體沒有足夠的彈性以適應需求的變化，專案壓力當然會一直居高不下。 由上述分析不難發現，提昇設計上的概念完整性對於軟體開發者而言，是非常重要的能力，因此，軟體開發者在設計上選擇讓步，無異於自廢武功，這樣將犧牲了設計概念的完整性，最後終究是無法解決問題或滿足客戶期待呀。 要如何不自廢武功？ 自廢武功無疑是下下策，但軟體開發者在面臨專案的巨大壓力下，要如何不自廢武功呢？顯然忽略設計的做法是不可取的，因此，單單只利用系統實作技能來彌補設計不完整的缺憾往往常會把問題弄得更複雜，這樣做其實是本末倒置的。筆者認為開發者應該重視設計概念的整體性，這樣才能用更簡單而富有彈性的設計來解決問題，而要達到這個目的，開發者必須更專注在問題分析與概念設計的能力。 因此，當軟體需求者提出了他們希望軟體應該要有的功能時，開發者還必須深入地思考為什麼他們會希望軟體應該要有這些功能，並深入地探討他們所面對的真正問題是什麼。因為軟體需求提供者只是站在客戶或使用者的觀點來看待軟體，技術並非他們的專業，所以他們對系統功能的理解很有可能並沒有辦法解決問題，因此開發者應該先找到需求者的問題而非功能。因為只有在了解需求者的真正問題後，開發者才能站在問題的角度來思考解決方案，也才能發展出適合的設計概念來解決問題。 筆者舉兩個實際的例子來說明概念設計對解決問題的重要性。有一個在開發中的系統，客戶發現在接收某種訊息時，其資料拆解出現了問題，我們探求其原因，發現在某些特殊 tag 之後，要跟隨在後面的 tag 資料都當成那個特殊 tag 的內容，而此系統的訊息資料拆解設計沒有支持這樣的概念，所以會造成這個 tag 的資料無法正確處理。 但因為此類訊息是屬於標準格式，而訊息規格卻沒有交待有這種特殊的 tag 規則存在，到底這是業界的不成文規定還是某些交易伙伴特有的做法呢？是不是還有其他的特殊 tag 呢？於是我們向客戶表示，必須要請他們提出更完整的資料，否則我們是無法處理這個問題的。 我們的回應，促使客戶更深入地去探討這個問題，據他們表示，以前的系統並沒有處理到這個問題，因此，得確還有一些特殊的 tag 沒被注意到，問題似乎並不如一開始所想像的那麼簡單。 然而，如果我們只針對客戶提出的問題來修改程式時，程式碼將會變得更複雜，因為在設計不改變的狀況下，所有接收 tag 處理的實作都會大受影響。但如果從設計概念上加入註記隨後出現 tag 都包括在某個 tag 內容的概念，就不會大幅影響原來程式的實作。只要在接收那個特殊 tag 處理的實作中設定註記，問題就可以迎刃而解，甚至可以變得更有彈性，例如可以設定某個 tag [...]]]></description>
			<content:encoded><![CDATA[<p>本文係投稿於 <a href="http://taiwan.cnet.com/">CNet</a> / <a href="http://www.zdnet.com.tw/">ZDNet Taiwan</a> 的初稿，並分為<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20125485,00.htm" target="_blank">上</a><a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20125774,00.htm" target="_blank">下</a>兩篇文章刊出，未經 ZDNet Taiwan 編輯，其內容可能會略有差異。</p>
<p>如眾所週知的，軟體開發專案具有高度不確定的特質。因此，為了降低需求變動的風險，在專案初期，軟體開發者往往會花費許多的心思，設計出具有彈性的軟體架構以適應未來可能的需求變化。大部分的開發者都了解軟體需求是不可能不改變的，但他們希望不管軟體需求如何變化，軟體開發的設計概念都不會因此受到影響或改變，如果可以做到這一點，軟體開發就會變得比較有效率，同時也能確保所開發之軟體的品質。</p>
<p>然而，現實總是和理想存在著一些落差的，專案的演變往往會超乎開發者事先的預期。尤其是當專案的驗收日期愈來愈接近時，專案可運用的資源也會愈來愈少，專案或許已不如剛開始時充滿了未知與不確定性，但相對地，專案的可變動性也愈來愈小。因此，在專案後期出現專案問題，或是需求的變動，相較於相同專案問題或需求變動在專案初期出現而言，會顯露出更為嚴重的危機與壓力的。</p>
<p>每個人都希望寧願事前多做一些風險管理，勝過事後的危機處理，而且後者的壓力是很容易讓做錯事的。然而，軟體易變的特質及專案環境的不確定性讓人難以捉摸，更不用說預測變化了，卻只能在事後才徒然留下「千金難買早知道，萬金難買後悔藥」的感嘆。但問題還是要解決的，到底軟體開發者在遇到這種危機時該如何處理呢？</p>
<h4>軟體品質的問題</h4>
<p>我們是否能拒絕變動？或許凍結需求，拒絕變動可以讓軟體開發成功，但這樣的做法卻不會讓專案成功。因為軟體專案如果無法符合軟體需求者的需求，專案並不能算成功，以軟體需求者的立場而言，客戶永遠是對的，他們並不在意技術有何難處，但卻會很關心軟體能否幫他們解決問題。所以，如果開發者所開發出來的軟體不能符合他們的需要、為他們創造出價值，軟體需求者會認為軟體品質並未達到目標，未符合品質目標，專案當然不能算是成功的。</p>
<p>如果變動無法拒絕，那麼只好接受它了，但這對軟體開發者而言，往往是重大挑戰。根據筆者參與軟體專案開發的實務經驗顯示，因為需求變更的原因，要向客戶去爭取專案合理的時程及增加開發成本其實並不容易。所以在專案時程與成本無法變動的情況下，想要解決專案的問題與滿足使用者的需求，很容易因此影響到產出軟體的品質。</p>
<p>其實從專案管理的三重限制（triple constrainst）的觀念應不難瞭解到軟體品質與專案時程、成本及軟體需求之間常會相互影響，因此，當專案時程及成本無法變動時，我們很容易可以理解軟體需求的變動將會影響到軟體品質。</p>
<p>而在實務上，軟體開發專案常會時程壓力、專案得到的支援與資源不足等原因，使開發者沒有足夠的動機、時間、與精力來分析問題以設計合理的解決方案，取而代之則是直接修改程式，以符合軟體需求者所提出的功能，就算發現了因此將會破壞了設計上的結構也在所不惜。就短期而言，在設計的結構上做一些犧牲，雖然如此可以換取增加軟體需求者所提出功能的空間。但長期下來，缺少對問題分析與完整設計的系統，自然而然會衍生出許多軟體品質的問題。</p>
<h4>解決問題的洞見觀瞻</h4>
<p>如此看來，軟體專案的需求變更，常會造成開發者的左右為難。計劃趕不上變化，現實就是變化無常的，所以藉由預測與控制要變動不會發生是不切實際的。但擁抱改變似乎沒有想像中的那麼單純，隨著需求的變化無常，程式碼也愈來愈複雜，造成更高的軟體出錯的機率，增添程式碼維護的困難度。</p>
<p>情況真的無法改變嗎？那也不見得，筆者認為想要脫離這種兩難的困境，開發者應先具有洞見觀瞻，認清軟體開發者應該面對現實，但應該避免因為捨本逐末的行為模式而形成自廢武功的後果。</p>
<p>如圖所示，表面上，忽略設計的行為雖然可以省下時間來修改程式，以解決眼前的專案壓力，但因為環境仍舊不斷地在變化，所以開發者忽略設計的狀況會一直持續地發生，才能節省更多的時間來對變化做出回應。然而，長久的忽略設計，卻會影響軟體設計的概念完整性，結果將會產生軟體設計結構不良的後遺症，專案壓力最後當然會不減反增了。</p>
<p><center><img src="http://www.lifeparty.idv.tw/blog/wp-content/uploads/2007/11/lost-design.PNG" alt="lost-design.PNG" /></center><center> </center><center></center>當開發者長期地忽略設計，他就不會花心思在軟體的概念性設計上，更不用說提昇軟體設計的抽象化思維的能力了。換句話說，開發者只能憑藉軟體實作的技巧來解決問題，但這是很危險的，因為這樣程式碼只會愈改愈複雜，變得難以令人理解，同時溝通起來也會變得格外困難，出錯機會也就增加了，造成更多的專案壓力。</p>
<p>另一方面，長期忽略設計，設計的概念不夠完整，也就是設計會遺漏一些重要資料，因此設計無法重覆地被運用，而實作上又充斥了許多的特例，存在許多的資料細節，因此要重覆使用也會有困難。也就是說，軟體的設計缺乏完整及一致性，其實作又與業務邏輯之間產生複雜的相依性，因而軟體各元件其實缺乏再用性與彈性。用軟體開發領域中常聽到的話來說，就是開發者要不斷地重覆「造輪子」，軟體沒有足夠的彈性以適應需求的變化，專案壓力當然會一直居高不下。</p>
<p>由上述分析不難發現，提昇設計上的概念完整性對於軟體開發者而言，是非常重要的能力，因此，軟體開發者在設計上選擇讓步，無異於自廢武功，這樣將犧牲了設計概念的完整性，最後終究是無法解決問題或滿足客戶期待呀。</p>
<h4>要如何不自廢武功？</h4>
<p>自廢武功無疑是下下策，但軟體開發者在面臨專案的巨大壓力下，要如何不自廢武功呢？顯然忽略設計的做法是不可取的，因此，單單只利用系統實作技能來彌補設計不完整的缺憾往往常會把問題弄得更複雜，這樣做其實是本末倒置的。筆者認為開發者應該重視設計概念的整體性，這樣才能用更簡單而富有彈性的設計來解決問題，而要達到這個目的，開發者必須更專注在問題分析與概念設計的能力。</p>
<p>因此，當軟體需求者提出了他們希望軟體應該要有的功能時，開發者還必須深入地思考為什麼他們會希望軟體應該要有這些功能，並深入地探討他們所面對的真正問題是什麼。因為軟體需求提供者只是站在客戶或使用者的觀點來看待軟體，技術並非他們的專業，所以他們對系統功能的理解很有可能並沒有辦法解決問題，因此開發者應該先找到需求者的問題而非功能。因為只有在了解需求者的真正問題後，開發者才能站在問題的角度來思考解決方案，也才能發展出適合的設計概念來解決問題。</p>
<p>筆者舉兩個實際的例子來說明概念設計對解決問題的重要性。有一個在開發中的系統，客戶發現在接收某種訊息時，其資料拆解出現了問題，我們探求其原因，發現在某些特殊 tag 之後，要跟隨在後面的 tag 資料都當成那個特殊 tag 的內容，而此系統的訊息資料拆解設計沒有支持這樣的概念，所以會造成這個 tag 的資料無法正確處理。</p>
<p>但因為此類訊息是屬於標準格式，而訊息規格卻沒有交待有這種特殊的 tag 規則存在，到底這是業界的不成文規定還是某些交易伙伴特有的做法呢？是不是還有其他的特殊 tag 呢？於是我們向客戶表示，必須要請他們提出更完整的資料，否則我們是無法處理這個問題的。</p>
<p>我們的回應，促使客戶更深入地去探討這個問題，據他們表示，以前的系統並沒有處理到這個問題，因此，得確還有一些特殊的 tag 沒被注意到，問題似乎並不如一開始所想像的那麼簡單。</p>
<p>然而，如果我們只針對客戶提出的問題來修改程式時，程式碼將會變得更複雜，因為在設計不改變的狀況下，所有接收 tag 處理的實作都會大受影響。但如果從設計概念上加入註記隨後出現 tag 都包括在某個 tag 內容的概念，就不會大幅影響原來程式的實作。只要在接收那個特殊 tag 處理的實作中設定註記，問題就可以迎刃而解，甚至可以變得更有彈性，例如可以設定某個 tag 有還原註記狀態的功能。</p>
<p>還有一個例子是，在一次專案會議中，某位系統分析者提出一個系統問題，她指出系統在案件的處理過程中，多人重複派送同一個案件會發生問題，她懷疑是因為多執行緒的案件分派機制所造成的，並認為如果讓案件分派不是多執行緒，問題就應該可以解決</p>
<p>不少開發者也認為讓分派機制不要那麼複雜就可以解決問題了，但他們也了解到，不用多執行緒，案件分派的速度會變慢，客戶很難接受這種做法，所以他們會很希望有人能和客戶協調溝通。</p>
<p>但筆者卻認為多執行緒的案件分派卻並不是問題的成因，雖然，在案件分派機制是多執行緒的情況下才會發生這個問題，但我認為問題較精確的說法應該是問題一直都存在，只是「多執行緒的案件分派」讓它浮現出來罷了。</p>
<p>筆者對提出問題的系統分析者質疑為什麼會有「多人重複派送同一個案件」的情況發生，她提到那是因為客戶的要求，因為客戶希望針對同一個案件，不同單位的人都可以處理同一個案件。原來是因為一開始系統分析者把案件的處理資訊與案件放在一起，但一旦當許多人可能會同時處理此案件時就會發生問題了，因為每個處理都是同一個案件，系統將不知如何分辨它們的不同。</p>
<p>這是一個典型的例子，缺乏整體概念設計的模型常常會讓問題弄得很複雜，系統分析者純粹以技術實作的眼光看問題，而非以問題領域的角度來建模，她把處理案件的案件與原始案件混在一起了，但以業務邏輯的概念來看，對某案件的處理本身是另一個案件，其有獨立的案件編號，所以只要用業務的眼光來修正設計模型就可以解決問題了，而不是取消案件分派的多執行緒功能。</p>
<p>從這兩個例子可以發現，分析出問題背後的問題，然後才能在概念上發展出有效的設計藍圖，才能用簡單而富有彈性的方式來處理問題，同時，這樣做也讓人可以容易理解與相互溝通，因為大家是針對問題領域來了解及溝通而不限於特殊技術。</p>
<p>問題分析並不需要花費太多的時間，因為只要找出問題的關鍵後，剩下的就簡單多了。當然，這需要不斷地練習，才能培養出敏銳地觀察力以及獨立思考的能力，而對於比較複雜的問題，也可以藉由集思廣義的方式來促進集體反思。良好的問題分析與概念化的設計能力才是軟體開發者能否適應環境變化的重要能力。總而言之，軟體開發者如果不去加強分析與設計的能力，專案壓力將會壓得他喘不過氣來，自廢武功往往是必然的結果，這只會耗弱軟體開發者的應變能力呀。但筆者相信只要我們多觀察、多思考、多學習，其實是可以打破這種宿命呀。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/262"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/262/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

