<?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/%e8%bb%9f%e9%ab%94%e9%96%8b%e7%99%bc/%e8%bb%9f%e9%ab%94%e5%93%81%e8%b3%aa%e6%96%87%e5%8c%96/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/6645</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/6645#comments</comments>
		<pubDate>Mon, 15 Aug 2011 11:11:43 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=6645</guid>
		<description><![CDATA[在同人簡要地回覆學長的留言之時，其實在我心中對於「做好產品」有一些還沒表達清楚的觀念。想等到有空的時候再補充我的想法，雖然後來看到學長說他不再寫文章與人爭辯了，但這些觀念其實不是為了爭辯而產生的，而是為了對話以分享意義，所以我還是決定把它們寫出來。]]></description>
			<content:encoded><![CDATA[<p>對於〈<a href="http://www.lifeparty.idv.tw/blog/archives/6624">做好產品一定能賺到錢</a>〉這篇文章，喲哪桑學長在 <a href="http://www.facebook.com/inpines/posts/161666513908256">facebook 的討論中</a>提出了他的看法。同人看到他的留言時並沒有時間完整表達我的看法，所以只是簡單地闡明我文章的題旨不是沒辦法把產品做好，而是認為客觀的好產品是不存在的。</p>
<p>在同人簡要地回覆學長的留言之時，其實在我心中對於「做好產品」有一些還沒表達清楚的觀念。想等到有空的時候再補充我的想法，雖然後來看到<a href="http://jonathanspeaking.blogspot.com/2011/08/blog-post.html">學長說他不再寫文章與人爭辯了</a>，但這些觀念其實不是為了爭辯而產生的，而是為了對話以分享意義，所以我還是決定把它們寫出來。</p>
<p>學長的留言提到：</p>
<blockquote><p>I find English can express my points better. My point, as well as Phil&#8217;s is that: Create a great product, and then charge it. This is the business we want to do. I don&#8217;t mean doing a product well. Thanks.</p></blockquote>
<p>同人猜想學長大概是看到我的文章提到「把產品做得再好」而認為我把做好產品誤解成把產品做好。但實際上，同人說把產品做得再好指的是把「做好產品」這件事做好，而不是把特定產品依照規格無誤地把產品開發出來。</p>
<p>有開發產品經驗的工程師都很能體會到做好產品要比把產品做好要困難許多。因為後者只需要具體的產品規格就不成問題，而前者則需要界定出對的問題，才能讓人朝向「正確」的方向去發展解決方案。然而，有時候你即使走的路是正確的，但不見得必然能得到該有的回饋，通常只是因為時機尚未配合。</p>
<p>所謂的「對」和「正確」都只存在主觀性而非客觀性，尤其是在市場上，群眾多半是盲目的，消費者總是非理性多過理性的，所謂的「對」和「正確」只是他們在市場上依據個人偏好所得到的結果，這並不代表多數人的選擇必然比少數人的選擇更「偉大」。</p>
<p>這種以成敗來論英雄的觀點其實是忽略了<a href="http://en.wikipedia.org/wiki/Efficient-market_hypothesis">市場通常不是有效率的</a>；在市場能獲利的產品通常不是走在時代尖端的高科技產品，而是接續附加價值高有實際應用的產品，後者並不是偉大的產品，而是基於多數人們保守心態的有用處的產品。</p>
<p>以策略管理的產品定位的角度來看，想要讓產品在市場上獲利應該先設定好目標客戶的特性，找出產品的水平品質（即功能）和垂直品質（即性能）之後，然後再投入適度的研發和技術把產品開發出來再向目標客戶來收費。因此產品的獲利可能只是市場行銷策略的成功，而不代表產品真的比競爭者的產品還要好；有時候，我們知道其它的產品比我們正在使用的產品更好，只是<a href="http://en.wikipedia.org/wiki/Switching_barriers">轉換成本的障礙</a>常使人望而卻步。</p>
<p>除了上面的原因之外，同人認為「做好產品」最大的不妥是在於語言上的不精確。Great Product 一如「成熟度」的偏頗，如同溫伯格說過的：</p>
<blockquote><p>「成熟度」這個字眼所傳達的並非一個事實，而是一種價值判斷－基於事實所做的一種詮釋，最起碼，它並不符合事實。<sup>[<a href="http://www.lifeparty.idv.tw/blog/archives/6645#footnote_0_6645" id="identifier_0_6645" class="footnote-link footnote-identifier-link" title="曾昭屏譯（2006），《溫伯格的軟體管理學（第一卷）－系統化思考》，p.59-60，經濟新潮社。">1</a>]</sup></p></blockquote>
<p>Great Product 的概念在於人們認為它比其它產品都成熟，但事實上，產品面對客戶的需求和他們想要解決的問題，並沒有<strong>對不對</strong>而只有<strong>有沒有效</strong>。<span style="text-decoration: underline;">「做好產品」很容易讓人流於個人主觀價值的偏見而阻礙了對問題分析的客觀的思考</span>，可怕的是語言的不精確會讓人陷入思考偏誤的陷阱當中，讓人堅持對錯批判經驗的執著。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/6645"  size="standard"   ></g:plusone></div><br />附註
&nbsp;<hr/><ol class="footnotes"><li id="footnote_0_6645" class="footnote">曾昭屏譯（2006），《<a href="http://www.anobii.com/books/013ad41f7a862e80dd/">溫伯格的軟體管理學（第一卷）－系統化思考</a>》，p.59-60，經濟新潮社。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/6645/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>做好產品一定能賺到錢？</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/6624</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/6624#comments</comments>
		<pubDate>Fri, 12 Aug 2011 09:32:16 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=6624</guid>
		<description><![CDATA[「好產品不一定能賺到錢」並不是一項迷思。其實它告訴我們一項真理：人想要靠開發出好產品而賺到錢，除了需要有能力把產品做出來之外，還需要其它因素的配合；把各種可能的因素加在一起，我們通常會通稱它叫機運。]]></description>
			<content:encoded><![CDATA[<p>喲哪桑學長認為<a href="http://jonathanspeaking.blogspot.com/2011/08/still-make-great-product.html">「好產品不一定能賺到錢」是因為人們沒有做出好產品而提出來的迷思</a>，不過同人並不贊同他的看法。</p>
<p>同人覺得喲哪桑的觀點讓人最疑惑的地方是有關「好產品」的定義，如何在開發產品之前具體而客觀地定義出什麼樣的產品是好產品，讓人能按照這樣的標準把產品開發出來。依據同人在系統開發的經驗來看，「好產品」的觀念總是只存在決定什麼好產品的「那個人」之<span style="text-decoration: underline;">主觀印象</span>當中，它通常是來基於他的價值判斷而產生的，但其他人不見得都會認同他對好產品的主觀價值認定。</p>
<p>當然，如果市場上大部分人都能認同「那個人」對產品價值的認定，那麼做出他認定所謂的好產品就能夠賺到錢。但如果市場上認同「那個人」對好產品概念的人並不多，即使產品做得多好也不能讓產品開發者賺到錢。</p>
<p>換句話說，開發者開發出產品的好壞並不能決定產品是否能絕對獲利，更關鍵的決定因素在於市場。就算開發者有能力開發出盡善盡美的好產品，但那並不代表市場就一定會肯定它的價值，因此「好產品不一定能賺到錢」並不是一項迷思。其實它告訴我們一項真理：人想要靠開發出好產品而賺到錢，除了需要有能力把產品做出來之外，還需要其它因素的配合；把各種可能的因素加在一起，我們通常會通稱它叫機運。</p>
<p>對於一些勇於實踐冒險精神的創業家而言，他們的成功是因為承擔風險而獲得的報酬，然而，不要忘記可能不乏有人和他們做了相同的事而失敗的例子，只是這些多半是「<a href="http://www.lifeparty.idv.tw/blog/archives/888">沉默的證據</a>」而讓人不得而知。</p>
<p>喲哪桑說，在 Phil 的演講中有提到幾個好產品的特性。他引用在他的文章中提到：</p>
<blockquote><p>更明確點說，做個好產品，好到人們會長期地一直留下來​用，好到它對人們的價值愈用愈高，而且，還能壓低公司的​變動成本。</p></blockquote>
<p>對於學長上面明確提到好產品的特性，同人不是不能認同。而是認為時空背景因素常會影響人們對產品使用的偏好；人們沒有長期使用某項產品，不代表它還不夠好，而是人們會感受到該項產品好用的時機還沒有到。很多時候，新穎或前衛的創新產品沒有受到人們的青睞，只是因為人們感知不到它的有用性，有時候不是因為產品易用性欠佳的原因，而是因為外在環境還沒有足夠的變因來刺激使用者的使用需求，這正是著名的<a href="http://en.wikipedia.org/wiki/Technology_acceptance_model">科技接受模式</a>所教導我們的觀念。</p>
<p>假設你打算花費了三個月的時間來做出一個好產品，你已經用專業的市場行銷眼光看到三個月之後將會大受歡迎的產品。於是你在工程方面投入了大量的功夫和心力，想辦法把產品做到盡善盡美。但假如你真的做出了無懈可擊的完美產品，是不是就會讓客戶認為這是有價值的好產品？答案恐怕是未必見得，因為你原先對市場的預測可能出現失誤、或是其間發生難以事先料想到時空背景的改變，使你的產品終究沒有得到客戶的認同。</p>
<p>喲哪桑說他們會每隔 1 天、3 天、1 個月、甚至是 1 年來檢查保留的比率，藉此來確認做出客戶覺得有價值的好產品。同人同意這種作法的確有助於增加產品在市場的成功，只是產品在市場上成功是因為產品做得好，這並不是客觀的事實，而是主觀的價值判斷。</p>
<p>其實產品的好壞很難客觀界定的，縱使你把產品做得好到大部分的人都愛用，也很難不讓其他的人覺得你的產品不好用或是不夠完美，尤其是在不同的時空因素下，同一個人對相同的產品常會有截然不同的評價。開發產品很難能夠做到滿足每一個人的需求，在現實因素的考量必須捨棄比較少人需要的功能時，難道是代表那些功能不好所以才會被捨棄嗎？</p>
<p>真相是捨棄不是因為它不好，而是因為多數的人<strong>現在</strong>不需要它，而且人很難預知將來會不會用到它。世界上從來不缺少比目前市場成功產品做得更完美的產品，但它們很多沒辦法成功地在市場上存活，並不是因為它們不是好產品，而是人們現在不太需要它們。同樣的道理，目前在市場上走紅的產品也不是因為它們是好產品，而是剛好符合市場上的條件；有一天這樣的條件會消失，而它們也將會被其它的產品所取代，就像它們曾經取代過的商品一樣。</p>
<p>最後喲哪桑學長說：<span style="text-decoration: underline;">要做出好產品，讓它更好。別畫唬爛、別搞政治，別搞關係，別打嘴炮</span>。同人很認同這句話，但卻也不由得想到過去的一段經驗。當時同人在一家開發資料庫資訊安全​的公司負責軟體設計及開發，那家公司的總經理常說他不想讓公司成為詐騙集團。他認為台灣軟體業的問題是<a href="http://www.lifeparty.idv.tw/blog/archives/6092">不重視把事情做好的紀律</a>，只靠業務和行銷吹噓而沒有把產品做好。</p>
<p>只是同人發現在他<a href="http://www.lifeparty.idv.tw/blog/archives/6039">主觀價值判斷上的執著</a>，無形之中產生了<a href="http://www.lifeparty.idv.tw/blog/archives/5589">組織的官僚特性</a>和<a href="http://www.lifeparty.idv.tw/blog/archives/5343">文化偏見</a>，其實他不是沒有在參觀者的面前做樣子，只是沒有意識他並沒有做到言行一致，結果讓產品一直「<a href="http://www.lifeparty.idv.tw/blog/archives/279">收尾巴</a>」收不完。這個經驗讓同人學習到了<strong>做好產品關鍵不在我們怎樣要求完美，而在於如何真的做到言行一致</strong>。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/6624"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/6624/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>軟體開發團隊的官僚特性</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/5589</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/5589#comments</comments>
		<pubDate>Mon, 11 Jul 2011 11:10:05 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=5589</guid>
		<description><![CDATA[在今年過農曆年前，看到以前閱讀《溫伯格的軟體管理學（第二卷）：第一級評量》所做的筆記，引發同人想要寫一篇文章探討軟體開發團隊的官僚特性。但由於工作轉換及其它寫作計劃的原因，直到現在才有時間分享我對軟體開發團隊的官僚特性之心得。]]></description>
			<content:encoded><![CDATA[<p>在今年過農曆年前，看到以前閱讀《<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010411034">溫伯格的軟體管理學（第二卷）：第一級評量</a>》所做的筆記，引發同人想要寫一篇文章探討軟體開發團隊的官僚特性。但由於工作轉換及其它寫作計劃的原因，直到現在才有時間分享我對軟體開發團隊的官僚特性之心得。</p>
<p>溫伯格說官僚是<strong>每件事都在掌控中，但是一切全都失控了</strong>。他提到：</p>
<blockquote><p>當專案規模變得相當龐大，通常就會因為專案成員對整體狀況缺乏掌控，不了解本身工作與整個專案的相關性，而導致官僚作風出現。</p>
<p>在這種情況下，大家一定會在不知不覺中做出危害品質的事，甚至會阻礙到專案的完成。這就是官僚－人們不明究裏地在做事。</p></blockquote>
<p>要評量軟體開發組織的「官僚特性」（bureaucratic nature），溫伯格認為可以藉由有多少事情在不明究裏的情況下完成。他指出在不明究裏的情況下完成事項，占完成事項的百分比就是評量官僚的一種方式。</p>
<p>想要減少團隊的官僚特性，管理者應該要讓團隊成員充分了解專案計劃。溫伯格提醒管理者有計劃還是不夠，應該要讓參與專案的團隊成員了解計劃，並且透過傳達與溝通讓每一個人都了解計劃。他強調只有高層了解的秘密計劃（而且就連高層自己也不太清楚這些計劃），勢必會在大型專案中引發官僚之災。</p>
<p>溫伯格的觀點解釋了在軟體開發團隊常見的官僚特性。在軟體開發過程中，人們不知不覺犯下危害軟體的品質或阻礙專案的進行的錯誤，通常並不是因為計劃不夠完整，而是因為團隊成員缺乏對專案計劃的整體了解。專案成員從專案計劃知道他的任務，但卻不知道他的任務和整體專案的關係。</p>
<p>換句話說，團隊成員知道他應該做什麼、和如何做，可是卻不知道為什麼要這樣做，工作只是由上面丟下來交辦，他只是奉命行事而已。比如說：</p>
<ul>
<li>程式開發者按照系統設計規格開發程式，可是卻不知道為什麼系統要這樣設計。</li>
<li>系統設計者按照系統分析規格設計系統，可是卻不知道為什麼系統要這樣分析。</li>
<li>系統分析者按照客戶提出的需求來分析系統，可是卻不知道為什麼系統會有這個需求。</li>
<li>管理者覺得開發者沒有把事情做對，可是卻總是不早點告訴開發者什麼叫做把事情做對。</li>
</ul>
<p>為什麼團隊成員在他們不知道為什麼的時候，不先溝通把事情的來龍去脈弄清楚才開始執行任務呢？可能是團隊成員的能力只能知其然，而不能知其所以然；也有可能是因為團隊成員的態度並不想多花心力去了解事情的根源。同人認為不管是成員能力或態度的因素，管理者都應該要為開發團隊的官僚特性負起最大的責任。</p>
<p>因為<strong>軟體開發團隊的官僚特性本質上是品質文化的問題，基本上和管理者的態度及核心價值觀有關</strong>。如果程式的開發者不能了解程式和設計、需求、乃至於其所要解決的問題，就很難確定他能夠在正確的問題方向上思考，以發展在正確問題下的有效解決方案。也許他做不到的原因是因為尚未培養面對問題獨立思考的技能和習慣，但如果管理者不能在團隊中建立<a href="http://www.lifeparty.idv.tw/blog/archives/128">共享語意庫</a>或增進<a href="http://www.lifeparty.idv.tw/blog/?s=%E6%B7%B1%E5%BA%A6%E5%8C%AF%E8%AB%87">共享意義</a>暢通的管道，要求開發者要有能力知其所以然只是緣木求魚罷了。</p>
<p>從另一種角度來看，團隊成員在態度上不想多花心力去了解事情的根源之真相，很可能是管理者在態度上並沒有鼔勵團隊成員多多參與討論、以及提供成員表達個人意見的管道。即使管理者在言語上聲稱他們願意接受不同的建言，但實際上面對團隊成員提出不同意見的質疑，卻是表現出不能接納建言的行為。慢慢地，團隊當中自然愈來愈沒有人願意表達他們的異議，成員傾向聽命辦事來規避把事情攬在自己身上，於是讓這樣的心態更加深團隊的官僚特性。</p>
<p>當然，管理者因為態度而加深開發團隊的官僚特性，最後必然會「個人造業個人擔」。最後團隊有想法、有抱負的「年輕人」會愈來愈少，只知道制度和規範而忽略思考創新的「老人」愈來愈多；這裡指的年輕人和老人不是基於年齡，而是基於成員面對問題的心態。當團隊的大部份成員都已經心態老化，思考僵化是軟體品質不良的根本原因，不論管理者加深團隊的官僚特性是有意或無意，他都必須為此承擔相對的代價。</p>
<p>「年輕人」比「老人」對事情的「理所當然」更不以為然，因此前者可以透過思考和創意來創造更多的可能性，這正是後者限於官僚特性所看不到的世界。</p>
<p>同人記得聽過某個長官曾經對下屬提的意見表示：「不要只提出問題，要有 solution！」不過接下來聽到另人激賞的反駁：「如果要有 solution 才​能提問題，那誰敢提呀？」表現對官僚特性的反抗，當然反抗的結束是最後反駁者終於離開那位長官的團隊。</p>
<p>同人不知道那位長官心中到底有沒有意識到「如果這麼快就可以有 solution，那根本就不成問題」的真相，但我知道他的管理風格無法適應會對「理所當然」質疑的思考者，他只能「管理」聽命辦事的工作者，也許只有加深團隊的官僚特性才能減輕他對管理彈性不足所反應的焦慮吧！</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/5589"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/5589/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>不要把 TDD 和做測試混為一談</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/6126</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/6126#comments</comments>
		<pubDate>Tue, 05 Jul 2011 11:22:29 +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=6126</guid>
		<description><![CDATA[最近讀到一篇文章〈不要盲目的 BDD / TDD，我對寫測試的看法〉，看完作者 XDite 反對不論如何都要導入 TDD 的理由，讓同人想提出我對這篇文章的看法。]]></description>
			<content:encoded><![CDATA[<p>最近讀到一篇文章〈<a href="http://blog.xdite.net/?p=2478">不要盲目的 BDD / TDD，我對寫測試的看法</a>〉，看完作者 <a href="http://blog.xdite.net/">XDite</a> 反對不論如何都要導入 <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> 的理由，讓同人想提出我對這篇文章的看法。</p>
<p>XDite 在文章中前半段，提到他對做測試的看法：</p>
<blockquote><p>我個人的看法是認為在大多數的情形下，你需要對你的「軟體」寫 "Test"，而且是要先寫 "Test" 再行撰寫程式，也就是  Test-Driven Development。因為程式碼會逐漸龐雜，沒有人可以 write code without bug，也不可能每次都有辦法用手測出來，加上有時候寫錯程式時的損失不是事後修理就有辦法彌補的，所以我們必須要寫 Test  Case，及早抓出問題。</p></blockquote>
<p>XDite 說這是所謂寫<a href="http://en.wikipedia.org/wiki/Test_case">測試</a>的重要性。但他強調這卻不是程式設計師「可以」不合時宜的盲目在「任何類型」的專案強行導入 <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">BDD</a> / TDD 的藉口。XDite 指出寫測試程式來確保程式正確性的解決方案，存在著額外多付成本的代價，亦即：</p>
<ol>
<li>「 寫測試 + 寫程式」 所花的時間，大概是純寫程式的 1.5 -2 倍時間。</li>
<li>「會寫 Test」、「正確的測到該測的部份」、「寫出好的測試」，都需要學習時間以及功力。</li>
</ol>
<p>於是 XDite 提出了四點原因，用來當成反對盲目 BDD/TDD 的理由。即使是程式設計師因為厭倦了維護在之前的專案後期的維護，因為修改程式碼而一再發生的問題（無論是小問題，大問題），而決定在下個專案，無論什麼專案類型都要導入 TDD / BDD，XDite 認為這在他眼中認為這是相當不正確的事情。</p>
<blockquote><p>1. 每個專案類型不盡相同，有的是要求高正確性且牽扯到金流問題且開發時間充裕。有的純粹只是 event，用過極丟。有的是幫人外包，只要求規格正確，開發時間不寬裕。有些則是混合型。有些部分的程式碼則是相當難以寫測試（如 View），C/P 值極低。應該考慮每個專案的類型甚至是 component 去決定哪部分該嚴厲的規定寫測試，而哪些部分可有可無。</p>
<p>2. Startup 前期應不應該導入 TDD/BDD ? 我認為不應該。為什麼，很多人都認為 TDD / BDD 是為了確保「程式的正確性」，所以無論如何我們都應該執行。卻忽略了 Startup 的成功要素是「快速驗證你的 Idea 的正確性」、「快速應付市場變化調整的速度」、「在市場廝殺中節省成本存活下來」。</p>
<p>3. 寫測試只是為了要能自動驗證「程式的正確性」、降低「程式出錯的機率」，但團隊合作開發程式最重要的是團隊中的「溝通」，大家對 function 和架構要有一定程度以上的理解，共同撰寫程式要有一定程度以上的 convention。變更任何重大架構（如 core function, db schema, 底層設計前）都要提醒大家。</p>
<p>如果每個人都只寫自己的，然後想改什麼東西照自己心情，沒有人想舉手之勞通知大家、跟隊友溝通。坦白說，那寫測試有個屁用，可能只是不會爆 production code，development 拉下來還是爛光光，還是要修到死。</p>
<p>完全不溝通、不制定規範，卻期待寫測試能夠解決一切，這樣的想法不是很奇怪嗎？</p>
<p>4. 無論如何，就算寫了再完美的測試，再完美的程式碼。程式還是可能在你完全預期不到的狀況爆掉，所以應該做的是要接受無論如何就是要修 bug 的這件事，然後想辦法把修 bug 的成本儘量壓低，也把因為 bug 會產生的損失也儘量壓低。</p>
<p>不要期待測試是萬靈丹。否則期待越大，失望也大。</p></blockquote>
<h4>到底是評論 TDD、還是做測試？</h4>
<p>同人覺得 XDite 這篇文章的論點令人混淆；他到底是在評論盲目導入 TDD 的行為、還是在探討開發者該不該多花時間寫測試程式，以確保「程式的正確性」？這兩者完全是不能相提並論的事情，同人很不能理解在前面提到寫測試程式來確保「程式的正確性」需要花更大的代價，而下一段就拿寫測試程式必然會忽略其它開發活動（如溝通、修正程式 <a href="http://en.wikipedia.org/wiki/Computer_bug">bug</a> 等活動）來否定 TDD/BDD 的價值。</p>
<p>難道 XDite 以為 TDD 就只是在做確保「程式的正確性」之測試而已嗎？假如 XDite 真的是這樣認為，那麼顯然他把 TDD 誤解成是在<a href="http://en.wikipedia.org/wiki/Software_testing">做測試</a>。不過，對於同人在文章後面留言提出的質疑，XDite 回應否定他把 TDD 誤解成寫測試，而是不喜歡一些沒有把 TDD 搞清楚的人，強行要把「TDD」和「測試」混在一起，綁在一起要求無論如何都要「TDD」。他提出了一種典型把測試跟 TDD 混淆綁在一起的狀況，是遇到下面這種混蛋邏輯：</p>
<blockquote><p>因為程式會爆炸，或者是以後改來改去又會暴很麻煩 =&gt; 所以我們需要寫測試 =&gt; 既然要寫測試，也許我們不應該事後補寫 Test Case，而是應該來試著 TDD。</p></blockquote>
<p>另外，XDite 還提到理想狀況開發者可以用 TDD 來開發產品，先寫測試去制定出規格，然後寫出實際程式通過測試，達到 <a href="http://en.wikipedia.org/wiki/System_design">System Design</a>。接著藉由不斷的寫新測試、新規格，然後寫出更多的程式，邊修邊測到 boundary。但現實狀況是，就算是熟悉 TDD 的開發者，他卻不一定是「<a href="http://en.wikipedia.org/wiki/Software_specification">規格</a>」、「<a href="http://en.wikipedia.org/wiki/Software_design">設計</a>」的主導者。</p>
<p>XDite 說在這樣的「現實狀況」，很多時候， Team 裡面有開發者不能強迫導入 TDD 的環節。強行推動只是互相絆倒和拖垮彼此的時程。XDite 認為 TDD 只在某種「單純」（專案成員素質接近一致，沒有 highly dynamic factor，目標單純）的專案、環境、Component 下適用。</p>
<p>雖然 XDite 對他的觀點，似乎並沒有留下和同人繼續討論的空間；我發現我後來的留言被當成 spam 處理。同人猜想也許他的文章說歡迎指教，但我的留言讓他感到威脅、或是覺得再繼續討論壓力太大，於是想中止和我就這個議題繼續討論。同人不想責怪他對我留言的反應，即使他這樣做只是要表達內心情緒的不滿，但我仍然不會停止對 TDD 的這個討論主題的思辨，並且會透過網誌來表達我的觀點。</p>
<h4>評論 XDite 的四點理由</h4>
<p>XDite 提到他不喜歡把「測試」和「TDD」綁在一起的混蛋邏輯，但它反對不管怎樣都要導入 TDD/BDD 的原因，卻又以寫測試案例的「極端」現象來反駁 TDD 的價值，顯得不合邏輯。</p>
<p>在 XDite 寫的四點原因中，除了第二點有明白地表達不該在 startup 前期導入 TDD 之外，其它三點看起來都好像是在批評寫測試程式的問題（還不論是不是先寫測試程式）。因此，這樣看來就很令同人費解；如果真如 XDite 所說的他不喜歡人們把測試和 TDD 綁在一起，怎麼會把寫測試程式出的問題都算在盲目導入 TDD/BDD 的頭上？如果連自己在談 TDD 的時候，都會和寫測試程式的問題牽扯不清，那麼又怎麼能責怪別人把「測試」和「TDD」綁在一起呢？</p>
<p>同人認為在 XDite 所提到的四點原因，它們並非錯誤，而是並沒辦法當作反對不管如何都要導入 TDD/BDD 的原因。雖然在第一點原因中 XDite 並沒有說錯，有些程式像是使用者界面程式的測試程式就很難寫，因此的確不大適合強行對他們進行 TDD。然而，當遇到這種情況的時候，使用者還是可以選擇用 Mock Object 把那些沒辦法寫測試程式的物件區隔起來，然後針對最多部分可測試具有演算邏輯的程式來進行 TDD。</p>
<p>因此，使用者界面程式沒辦法建構 TDD 的測試程式對於 TDD 而言，並不是什麼太大的問題。因為基本上 TDD 不是用來當做測試的工具，而是用來設計可以驗證符合使用者真實需要的工具。所以開發者只要針對可測試、或該測試的部分建構測試案例就夠了。TDD 的目的是要確認花費最小的努力來滿足使用者的需求，測試案例所要求的不是全面的完整，而只是確認達到剛好達到滿足需求的邊界，這將會促使開發者先以界面的思維來整合系統各要件。對 TDD 測試案例比較重要的問題，是如何設計可測元件與非可測模組之間的界面。</p>
<p>至於 XDite 提到對於某些程式沒有必要寫 TDD 的測試程式，同人倒會很好奇有什麼客觀標準、或是有誰可以決定什麼程式沒有建構 TDD 測試案例的必要？在同人導入 TDD 的經驗中，就曾經有開發者要求 Business Object 不要寫 TDD 的測試案例，當時他們的理由是它們沒有什麼太複雜的邏輯、而且不大容易會變動，所以應該不需要為它們建構 TDD 的測試程式。</p>
<p>然而，事實證明，接受開發者這個要求的決定，是整個系統發生苦難的開始。因為所有的問題都從 Business Object 的瑕疵開始引爆，直到把 Business Object 也納入 TDD 測試案例的範圍，系統程式的品質才能達到令人接受的水準。</p>
<p>再來，對於 XDite 唯一有討論到導入 TDD 的第二點，他認為 startup 前期不應該導入 TDD，因為 startup 的成功要素是「快速驗證你的 Idea 的正確性」、「快速應付市場變化調整的速度」、「在市場廝殺中節省成本存活下來」。然而，同人對此卻認為恰好相反，TDD 正是「快速驗證你的 Idea 的正確性」、「快速應付市場變化調整的速度」、「在市場廝殺中節省成本存活下來」的利器。</p>
<p>為什麼？不用 TDD，人們多半傾向會以自己所相信的基本假設來解答問題，也就是以自己的經驗或熟悉的事物，從核心出發來發展解決方案，以期待把事情做正確。在這種情境下，人們通常會想得太多，而容易有過度設計（over engineering）的傾向，而 TDD 則可以讓人回歸到從問題來決定系統的邊界，再以最符合經濟效益的方式來解決問題。所以自然能夠以最省時及省力的方式來做正確的事情，更可以在市場上獲得致勝關鍵。</p>
<p>XDite 說他不同意「快速驗證你的 Idea 的正確性」、「快速應付市場變化調整的速度」、「在市場廝殺中節省成本存活下來」，是「對  TDD 再適合不過」。但同人很清楚這「對於熟悉 TDD 的開發者而言」是很自然的，顯然 XDite  是忽略了我認為這句話成立的前提，在於開發者是否能熟悉使用 TDD 的節奏。</p>
<p>如果開發者熟悉 TDD  的節奏，當他沒辦法寫出測試程式的時候，代表他對系統所要解決的具體問題還不夠清楚。為了要弄清楚他必須更清楚去溝通，而且 TDD  的習慣會促使他傾向以使用者的情境去溝通，而不是拿功能要使用者告訴他該做什麼。只有在開發者瞭解使用者的情境之後，開發者才能具體而正確地寫出驗證程式的測試案例，這說明<strong>在 TDD 寫的測試案例不是做測試而是在做設計，而且不可能因為寫 TDD 的測試案例而讓開發者不做溝通</strong>。</p>
<p>所以 XDite 提出的第三點和第四點原因，或許對於做測試是可能成立，但在 TDD 的情況下卻是可能性很低。因為除了建構 TDD 的測試案例需要了解使用者情境更需要溝通之外，TDD 的測試案例本身就是有用的溝通工具。TDD 的測試案例是能夠經過驗證的具體規格、同時它也是相關元件、API、或是模組的範例程式。</p>
<p>當然 TDD 更不會有太要求測試程式的完美，而忽略修正 bug 的問題，因為 TDD 的測試案例並不要求完美，而只是夠用就好。而且 TDD 在實際上可以用較低的成本來修正 bug，因為它能夠自動發現錯誤，再加上重構能夠逐漸改善程式碼的品質，TDD 沒辦法確保程式一定不會出現錯誤，但它總是能夠以較低的成本得到較高品質的程式碼。</p>
<h4>TDD 必須很「單純」？</h4>
<p>XDite 說 TDD 只在某種「單純」（專案成員素質接近一致，沒有 highly dynamic factor，目標單純）的專案、環境、元件下適用。但在同人導入 TDD 的成功經驗中，很不巧就有專案、環境、元件不單純的例子。</p>
<p>在一個國內知名金控公司的銀行外匯系統建置專案，表面上專案的目的是為了建置新一代的外匯系統，而不想受制於舊有系統和廠商的牽制，但實際上客戶高層的想望是要架構能夠整合機構其它系統的基礎建設平台。然而，當詢問客戶高層對系統目標的意見時，他們給的回答竟是「把系統做到令客戶咋舌」這種有說等於沒說的答案。</p>
<p>專案的成員並非來自開發組織的單一部門，而是從各個組織挑選各種經驗和背景的人，雖然有專業能力資深的人，但也有對相關技術不熟悉的成員。可以想見，在專業、技術、能力、背景如此懸殊的情況下，因為「人的問題」而發生團隊衝突是很難避免的，這個專案的團隊衝突的課題，正好提供我<a href="http://ndltd.ncl.edu.tw/cgi-bin/gs32/gsweb.cgi/login?o=dnclcdr&#038;s=id=%22095NTUS5396084%22.&#038;searchmode=basic">碩士論文</a>的研究動機。</p>
<p>當時開發團隊過去沒有接觸過相關問題領域的經驗（事實上是客戶指定不希望找對有金融經驗的人來開發，公司沒有開發過相關領域的專案，而有不錯的系統建置專案，才是客戶會選擇我們的主要原因）、開發環境也是用開發團隊過去完全沒有經驗的技術。</p>
<p>客戶指名這個專案要使用 <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA</a> 架構，由前端 <a href="http://en.wikipedia.org/wiki/JavaServer_Faces">JSF</a> 以 <a href="http://en.wikipedia.org/wiki/Webservice">Web service</a> 呼叫到 <a href="http://en.wikipedia.org/wiki/Application_service">Application Service</a>，呼叫後端直接存取 <a href="http://en.wikipedia.org/wiki/POJO">POJOs</a> 或是傳送訊息的服務、而中間物件的傳遞則透過 <a href="http://en.wikipedia.org/wiki/XStream">XStream</a> 的序列化以 <a href="http://en.wikipedia.org/wiki/JAX-RPC">JAX-RPC</a> 進行遠端傳送、至於元件包括軟體架構也都是從無到有按照系統需求逐漸演化成型。</p>
<p>專案團隊大部分的人都沒做過 TDD，加上這麼多「高度動態的因素」，而導入 TDD 竟然能夠成功，是因為我們運氣好嗎？這麼說必須忽略開發組織守舊勢力對新方法論、架構和技術的反撲，否則就很難解釋公司總經理的質疑和反對。實際的情況是我們不是運氣好，而是用對的方法讓我們做好準備。當公司高層開始質疑的時候，我們早就已經透過 TDD 快速驗證我們的方法沒問題，而讓總經理無法否決我們的設計成果。這讓人目睹 TDD 的真正價值所在，不是確認「程式的正確性」，而是讓人有勇氣並保持簡單的節奏。</p>
<p>同人認為 TDD 的成功並不在 TDD 自動確認「程式的正確性」，而在於TDD 讓人有勇氣把事情做好，讓人遵循良好解決問題的節奏和紀律。那就是：1.確認問題；2.依照問題情境，發展用來驗證方案的標準；3.設計方案並執行驗證，以達符合驗證標準；4.視組織需要改善方案，再次執行驗證以確認符合標準。</p>
<p>依照這樣的節奏和紀律，可以讓人在確認方案做正確之前，已經驗證方案是用來解決正確問題，以避免過度設計和設計不足的兩難。這正是傳統方法很難避免的問題；即使開發者擁有熟練的開發技術，但少了在事情做對之前先做正確事情的紀律，品質問題正是因此而叢生。</p>
<h4>現實的真相</h4>
<p>XDite 用「理想狀況」來反駁用 TDD 來瞄準、射擊、修正後再射擊的觀念，他說很多時候， Team 裡面有開發者不能強迫導入 TDD 的環節，強行推動只是互相絆倒和拖垮彼此的時程，這是所謂的「現實狀況」。這麼說似乎是意味了 XP 敏捷方法的 TDD 實務無法在「現實狀況」實行，而是「理想狀況」。這種說法對同人其實並不陌生，就像我在〈<a href="http://www.lifeparty.idv.tw/blog/archives/163">羅馬不是一天造成的</a>〉這篇文章所提到的情形：</p>
<blockquote><p>同人偶爾會與 X 君分享我的工作心得，他很羡慕我能夠堅持設計的理想，遵循好的設計原則及開發方法發展出軟體架構，像他就沒有這樣的機會。而和同學分享我的工作成果時，他則認為我堅持設計理念可以成功，是因為我們公司有足夠的資源可以讓我們玩，換成是小公司，就不會有這樣的成功條件。</p></blockquote>
<p>其實同人在那篇文章所提到的概念、架構和技術的驗證，所用的方法正是 TDD。但同人分享成功經驗看到人們的反應卻發現，除了羡慕和佩服之外，多半是認為我剛好遇到足夠的條件來支持我實踐理想，而他們的「現實狀況」一定不允許他們這樣做。</p>
<p>假如真的是「現實狀況」不允許開發者導入 TDD，那麼面對開發出來的軟體品質不彰，他們採取了什麼行動來面對現實呢？以同人在一家開發軟體產品的 startup 公司看到的「現實狀況」來看，他們只是試著更努力而辛苦地把過去的工作做得更好，可是彷彿都一直不能如願。</p>
<p>同人在那家公司分享過我的 TDD 的經驗，RD 經理認為或許應該要做 TDD，可是因為使用資料庫的關係，會讓 TDD 很難做到或是做了沒有太大的效益。同人並不太瞭解為什麼他會有這種顧慮，因為按照我過去的經驗，資料庫的部分可以用 Mock Object 或是 Hash Map 版本的實作來區隔開來，而且這樣做有優化設計的好處。不過，同人不便公開質疑主管對 TDD 的顧慮，而是選擇尊重他在「現實狀況」下的決定；等到適當的時機再導入 TDD，除了眼下的問題需要被克服之外，還要讓開發者們的步調都能一致。</p>
<p>直到同人離開那家公司之前，TDD 都是一直被人們掛在嘴巴上說，但從來未曾真正去做。然而，隨著需求愈來愈多，程式碼也愈來愈複雜。這時候，關於軟體品質愈來愈殷切的議題便是元件很難被獨立測試，而是必須整塊合在一起才能測試，但這在除錯上很沒有效率。於是各個元件要獨立測試變成一項非常重要的需求，但滿足此項需求最大的問題便是軟體架構需要動大刀，而更緊急的嚴重問題便是有一大堆在客戶端的 P1 和 P2 的 bug 需要解決。</p>
<p>於是在龐大的時程和品質壓力下，常讓 RD 和 QA 沒辦法在時限內產出符合品質要求的軟體。我們用的方法，就是一次又一次的讓 RD 以<a href="http://en.wikipedia.org/wiki/BDUF">大規模前置設計</a>（BDUF），然後等程式開發完成之後再 handover 給 QA。雖然表面上公司採用敏捷的開發流程，每天在固定時間召開 <a href="http://en.wikipedia.org/wiki/Stand-up_meeting">Daily Stand-Up Meeting</a>，但是看起來專案管理者的腦袋並沒有換成敏捷的思維，仍然是期待以更精確的預測來改善專案的進展，即使是他們對專案狀況的預估從來沒有準確過。</p>
<p>在這種「現實狀況」下，雖然同人已經提醒 <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29">Scrum</a> 偏重管理面而非工程面，但由於 RD 經理對 TDD 仍然有疑慮而不敢貿然採用它來提昇程式的品質。整個開發團隊只是一遍又一遍地用和昨天用過的方法，來試圖解決今天相同的問題，但我發現專案管理者好像不合邏輯地希望得到不一樣的結果。它正符合愛因斯坦對精神錯亂所下的定義：</p>
<blockquote><p>一遍又一遍做同樣的事，卻期待不同的結果。</p></blockquote>
<p>同人看到專案管理者對「現實狀況」的理解是，因為開發者在事前（不用心而）想得不夠多，所以不能在一開始就把事情做對，而導致軟體運行發生錯誤。但同人認為「現實狀況」的真相卻是，關鍵在於開發者沒有辦法做正確的事情，在很多時候設想了太多無謂的問題，而把心力分散在處理瑣碎的事情，而無法專注在關鍵問題上思考。</p>
<p>這是因為無法快速驗證方案對解決問題的效果，往往在開發者花費大量心力脫離「<a href="http://zh.wikipedia.org/zh-tw/%E4%BA%BA%E6%9C%88%E7%A5%9E%E8%AF%9D#.E7.84.A6.E6.B2.B9.E5.9D.91">焦油坑</a>」之後，才發現真實情況有很多地方是無先無法預料到的。換句話說，這不是開發者做的東西不對或是不好，而是面對適應變化，沒有把握「動作要快、行動要小」<sup>[<a href="http://www.lifeparty.idv.tw/blog/archives/6126#footnote_0_6126" id="identifier_0_6126" class="footnote-link footnote-identifier-link" title="曾昭屏譯（2006年），《溫伯格的系統管理學：系統化思考（第一卷）》，經濟新潮社。">1</a>]</sup>的原則。</p>
<p>當然在「現實狀況」下，導入 TDD 的實務不見得真的能夠有效地解決問題，對於任何一種開發方法論，我們都不應該盲目導入，而是要弄清楚它的適用範圍和限制，TDD 當然也不例子。然而，對於把 TDD 和做測試混為一談，然後藉此推測團隊中「一定」有 TDD 不能強迫導入的環節，強制推行只會互相絆倒和拖垮彼此時程，同人認為這是扭曲 TDD 當成做測試的繆誤。</p>
<p>使用 TDD 來開發軟體，開發者實際花費在測試案例的時間並不會很長。因為程式開發者不可能只寫程式而不驗證自己的程式碼，否則無法確認程式符合規格，就不能認定他已經寫完程式了。既然驗證程式碼是他的責任，那麼測試先行只是確認程式碼符合規格的一種方式，這樣只是把後面應該執行的工作先做好，並不會增加開發者額外的工作量。</p>
<p>因此建構 TDD 的測試案例並不需要額外的工作量、也不大可能會因為執迷於測試而沒有花時間溝通共通架構、或是程式的 <a href="http://en.wikipedia.org/wiki/Debug">debug</a> 時間。又能節省開發者因為想太多而多花費過度設計的時間，而且可以支持驗證程式的重構來加強程式的結構，不會因為增加功能而影響程式碼的品質。</p>
<p>TDD 在開發程式之前先寫測試案例的用意，並不是為了及早自動抓出問題。雖然這通常是採用 TDD 能夠產生的附加價值，但 TDD 先寫測試程式的精神是為了驗證未來方案能夠符合需求，以確認方案是在正確的命題方向上發展。開發者發展解決方案，每前進一小步，都能夠知道這一步離他的目標更接近或是遠離，這讓他可以馬上採取行動來調整方向以減少偏差。於是開發者可以做到真正的面對現實，這正是掌握適應改變行動要快、動作要小的原則。</p>
<h4>不理究理者的未嘗知義</h4>
<p>採用 TDD 來開發軟體，並不能做到確保程式的正確性、或是降低程式出錯的機率。因為要做到這個目的你就必須「預測」程式會發生問題的一切可能性，並且預先把它們都放到測試案例中，才有可能達到這些目的。然而，事先做預測已經違反了敏捷開發的基本原則，也違反了 TDD 的基本精神，認為 TDD 的目的是為了確保程式的正確性、或是降低程式出錯的機率而把它和做測試混為一談，這只是不明究理的人未嘗知義的偏見。</p>
<p>就像在網路社群中，<a href="http://www.artima.com/weblogs/viewpost.jsp?thread=216434">James O. Coplien 以「宗教信仰」形容 TDD 的迷思</a>算是最典型的代表，它以 TDD 不可能達到測試良好的涵蓋率來批評它的效率不如傳統的軟體工程方法。同人曾經<a href="http://www.lifeparty.idv.tw/blog/archives/266">評論過這種觀點的繆誤</a>：</p>
<blockquote><p>品質的問題並不是測試效率太低；而是開始測試的時間拖得太久，使得分析設計階段的缺陷不斷地擴散而使開發人員窮於應付。例如開發者在設計的過程中有沒有去思考設計驗證的問題，還是把這個責任推給後續的品管作業，例如 code inspection，或是各種形式的審查作業？</p>
<p>這個答案無關乎方法論本身的優劣，而是關乎開發者面對問題的態度，這對品質有著直接而深遠的影響。沒錯，我們需要專注於思考，但思考的重點並不在用那一種檢驗方式比較有效率，因為那樣我們將會落入品質是檢驗出來的迷惘當中。而是應該思考，對這個問題為什麼我會這樣設計？我如何驗證它是可行的？有沒有可能它會無法解決問題或造成其它我沒有想到的問題？</p></blockquote>
<p>把做測試和 TDD 混為一談的觀點，忽略了 TDD 的價值不在檢驗程式的正確性，而是找出足以解決問題的系統邊界的設計過程、以及面對目標採用有效的節奏把事情做好。對於 TDD 而言，測試不是用來確認程式沒有錯誤的目的，而是定義系統邊界的手段與過程，因為品質的關鍵不在於確認沒有錯誤的程式，而是從程式接口之間發現軟體自然演化的脈絡；學習庖丁解牛的精神，以游刃有餘的技法來體會軟體開發之道。</p>
<p>至於 XDite 在意以「混蛋邏輯」把 TDD 和測試綁在一起，同人覺得根本就是沒有必要地在鑽牛角尖。當程式設計者說他想要寫測試程式來確認程式的品質，並不見得他真的是把測試和 TDD 綁在一起；而且就算是他真的把測試和 TDD 綁在一起，同人也認為無傷大雅。有時候，管理者不見得會瞭解程式開發者所表達 TDD 的正確的觀念，所以開發者必須學會用不太精確但表達到重點的說法對管理者提出需求。</p>
<p>這也就是說，對於程式設計者而言，他所需要的是擁有能夠提昇他程式品質的方案，而 TDD 是他想要可能可以符合需要的候選方案之一。提出測試的附加價值是讓管理者比較能夠接受的說法，當然程式開發者也有可能真的把測試和 TDD 綁在一起，但即使這樣也沒有關係。因為當他實際採用 TDD 開發程式後會發現程式品質的提昇不是測試，而是在<a href="http://en.wikipedia.org/wiki/Edge_of_chaos">系統邊界附近</a>發生<a href="http://en.wikipedia.org/wiki/Self-organization">自我組織</a>的演化過程。</p>
<p>很多時候，我們真的沒辦法期待人們觀念正確才開始動手執行，因為那樣等於你什麼都不用做，而且軟體開發的重點不是理論怎麼說，而是實務上怎麼做，程式開發者從實務上的執行才能真正瞭解，TDD 不能跟做測試混為一談。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/6126"  size="standard"   ></g:plusone></div><br />附註
&nbsp;<hr/><ol class="footnotes"><li id="footnote_0_6126" class="footnote">曾昭屏譯（2006年），《<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010341309">溫伯格的系統管理學：系統化思考（第一卷）</a>》，經濟新潮社。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/6126/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>絕對支持品質流程的宣稱</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/6039</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/6039#comments</comments>
		<pubDate>Thu, 23 Jun 2011 08:27:51 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=6039</guid>
		<description><![CDATA[在公司高層這種態度和形成的公司文化氛圍之下，公司產品最後會變成「把做好的東西丟到牆的那一邊去」就不足為奇了。再加上以西方優越感產生文化的價值批判，在這種情況之下，QA 對產品品質的提昇有多少著力點呢？同事丙的離開做出了最好的回答。]]></description>
			<content:encoded><![CDATA[<p>最近在兩年前寫過〈<a href="../archives/488">聚餐也談品質流程</a>〉的文章，看到當時 <a href="http://www.lifeparty.idv.tw/blog/archives/488/comment-page-1#comment-8821">satomi 在迴響中提到</a>：</p>
<blockquote><p>我看了很多公司，每一家都宣稱絕對支持 QA 啊！</p></blockquote>
<p>這句話讓同人心中無限感觸。感觸之一是 satomi 原來就認識同人的許多同事，包括同事丙和同事乙，而且和同事丙一樣，satomi 是非常有經驗的 QA。這當然是我在寫完那篇文章之後才知道的事情，然而現在看這篇文章，感覺像是跟很多老朋友在進行有關品質的對話。</p>
<p>其實還有更大的感觸之二，記得我當初在寫這篇文章的時候，我認為公司的品質文化是重視方法來提昇品質，這是公司高層對品質的承諾。因此，當 satomi 留言回應「QA 應該要可以提昇品質，但是公司從來沒有授予這個 QA 團隊做到這件事的權限」時，同人覺得公司一直給予 QA 足夠的權限而並不認為是如 satomi 說的那樣。</p>
<p>然而，兩年後有機會再回頭看到那篇文章之後，才看到 satomi 留言的先見之明。原來同人當初對公司的品質文化的看法並不正確，即使公司高層宣稱絕對支持 QA，但在行為上的表現卻並非如此，而是並沒有實際賦予 QA 足夠的權限來提昇產品的品質。</p>
<p>當然，同人相信同事丙當初不見得有「認為公司表面上表示絕對支持 QA，但骨子裡卻從來沒有授予這個 QA 團隊做到這件事的權限」。不過我很確信他今天不會認為公司高層的行為真的如其所宣稱，在行動上支持 QA。</p>
<p>否則，原先對公司發展遠景抱持希望和品質管理工作懷有熱情的同事丙，應該不會在同人離開公司之後，選擇在同一個時間點也離開公司。以同人在離職之前對他的觀察，我發現他在會議中相較於以前更少表示他的看法，感覺到他似乎已經不像過去對工作懷抱熱情，即使他還是努力工作為減少公司產品的 bug 而奮鬥不懈。</p>
<p>是什麼東西讓同事丙澆熄他的熱情？從同人後來私下和同事丙的聊天之中，可以確知是和公司高層對開發流程的態度有關。公司高層對品質的觀念和態度很有問題，有問題是指因應公司產品的複雜性和解決客戶問題方面，他們採用了不大適當的產品品質模式；以「照章行事」的方式來進行品質的管控而非「把穩方向」來做正確的事情以提昇品質。</p>
<p>在同人和同事丙共識的兩年中，我曾不只一次看到他和公司高層之間在開發流程的溝通中產生火花。對於高層提出新的開發流程，同事丙為了確認「我們真的要以瀑布法來開發產品嗎？」經常會造成和高層不悅的言語交鋒。在同人眼中看到這一切，我覺得使用「瀑布法」也許並沒有什麼不好，但我發現比較大的問題是高層侷限於自己的眼光，而不能用別人的觀點來看到自己觀點的問題。</p>
<p>同人從另外一件事更顯著地看到高層有這種侷限。有一次，在一個公司高層找同事丙、研發經理研究該如何解決客戶端問題的會議中，同事丙提出對公司高層提出的解決方案的意見。公司高層告訴同事丙，他應該先想好解決方法再提出他的意見。同事丙則不以為然地表示，如果要提意見之前都要先想好解決方案，那麼誰敢提呀！</p>
<p>因此，在公司高層這種態度和形成的公司文化氛圍之下，公司產品最後會變成「把做好的東西丟到牆的那一邊去」就不足為奇了。再加上<a href="http://www.lifeparty.idv.tw/blog/archives/5343">以西方優越感產生文化的價值批判</a>，在這種情況之下，QA 對產品品質的提昇有多少著力點呢？同事丙的離開做出了最好的回答。結果真的讓 satomi 說對了，公司的確是沒有賦予 QA 足夠的權限來提昇產品品質。</p>
<p>當然，產品品質不能提昇其實不能全怪公司高層。同人相信他絕對是有心要把產品做好，絕對也不是只有口頭上說說而已，但只是他的心智能力和行為沒辦法達成一致，非不為也，實乃不能也。從他老是把「把事情做對」掛在嘴裡，就知道他不知道「做正確的事情」可能才是品質不能提昇的最大瓶頸。去年年底，同人才發現他根本不能分辨工程的<a href="http://en.wikipedia.org/wiki/V%26V">驗證（validation）流程和確認（verification）流程</a>的差異，還問我「做正確的事情」是什麼意思，不是「把事情做正確」就行了嗎？</p>
<p>因此，我們真的不能怪罪公司高層<a href="http://www.lifeparty.idv.tw/blog/archives/4311">只知道「照章行事」而不知「把穩方向」</a>。你可以看到那些沒有辦法改變品質文化的高階主管，他們的無能是來自於無知，所以真的不能太苛責他們。</p>
<p>也許在夜闌人靜中，有心而無力改變的高階主管會反省自己白天錯誤的愚蠢行為，然而，一旦相同情境再度聚合，他們就是無法不在別人面前表現出愚蠢的樣子。這代表他們對於提昇軟體的品質這檔事，知道的很有限，可是又不想讓人知道他們知道的有限，也許需要更多失敗的境遇來磨鍊出成熟的心性，才能<a href="http://www.lifeparty.idv.tw/blog/archives/205">走出自己穴居的洞穴</a>，而看到不一樣的世界。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/6039"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/6039/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>掌握設計演進的節奏</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/2784</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/2784#comments</comments>
		<pubDate>Tue, 19 Jan 2010 10:07:32 +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=2784</guid>
		<description><![CDATA[在軟體開發的過程中，有沒有方法可以避免我們浪費心力在無謂的堅持上，然後用比較簡單而又有效率的方式來完成我們的工作呢？經過與同事上面的對話，同人想到運用到我在分享會中所提到的觀念與實務，可以很輕易地掌握設計演進的節奏。藉由此篇文章分享出來，也算當做同人在 1/9 敏捷開發分享會後的一個註腳吧。]]></description>
			<content:encoded><![CDATA[<p>在 <a href="http://cb.esast.com/cb/wiki/9584">1/9 在新竹舉辦的敏捷開發方法分享會</a>，當同人分享到 XP <a href="http://en.wikipedia.org/wiki/Refactoring">Refactoring</a> 實務的經驗時，台下有一位聽者剛好也是我目前的同事提出一個問題：該由誰來決定何時應該重構的問題。同人當時回應重構多半發生在軟體架構的設計上，一般開發應用程式的程式員通常比較不太會有機會重構。在專案每天早會上，團隊各個成員會報告他們目前進行的工作狀態，當同人發現他們遇到架構面上的問題，我便會著手進行架構的重構以避免系統發生疊床架屋的現象。</p>
<p>同事好奇重構的決定是否有客觀的標準，同人表示這部分多半還是個人主觀的經驗居多。在同事後來開車載我回台北的路上，我們再次談到決定重構的時機。同事覺得重構的時機似乎不是一件容易掌握的事，同人進一步地解釋，當時我們在應用程式的開發沒有太多重構的機會最主要的原因，是因為在架構上力求簡潔而單純的設計概念，使得應用程式的開發已經變得很簡單，實在不太需要運用重構用來增加設計的彈性。</p>
<p>趁這個機會，同人向同事強調架構的彈性不應該以需求不得改變為前提，而是要能夠因應「有限度」的變化而發展而不斷地調整及演進。也就是好的架構並非從恒久不變的核心來出發，而是要先去識別出問題的輪廓才找得到適用的核心。同人經常在軟體開發的實務中看到，人們花費了太多的心力來堅持不變的核心，到最後才會發現原來問題是出在自己對問題假設錯誤。</p>
<p>那麼，在軟體開發的過程中，有沒有方法可以避免我們浪費心力在無謂的堅持上，然後用比較簡單而又有效率的方式來完成我們的工作呢？經過與同事上面的對話，同人想到運用到我在分享會中所提到的觀念與實務，可以很輕易地掌握設計演進的節奏。藉由此篇文章分享出來，也算當做同人在 1/9 敏捷開發分享會後的一個註腳吧。</p>
<h4>設計演進的基準</h4>
<p>軟體開發與其它的產品開發有一個很大的不同，在於軟體通常很難在一開始就定義出明確的需求規格，取而代之的是軟體的發展方向，是用來解決利害關係人在真實世界所面臨的問題。這也是使用 IPO 傳統目標導向來開發軟體經常遇到的困難，當需求的改變不可能不經常發生的時候，軟體開發在品質文化上就不應該採用「照章行事」的模式，而是應該建立具有回饋機制的開發系統來把穩軟體的開發方向。</p>
<p>可以「把穩方向」的軟體開發系統應該具有什麼樣的回饋機制呢？根據<a href="http://www.anobii.com/books/013ad41f7a862e80dd/">溫伯格在他的軟體管理學的觀點</a>，管理者賴以把穩方向的回饋機制，必須是可以直接及穩定的觀察專案目前的狀況、並且比較專案目標與現況的差異、然後以後續如何減少差異為目標改變或調整計劃、最後再根據計劃採取行動來改善專案狀況。其中有關於直接而穩定的觀察，直接代表肉眼可直接觀察的專案結果，穩定代表不同觀察者每次觀察的結果都相同。</p>
<p>相信從以上的觀點，我們可以清楚看到「把穩方向」的品質文化與敏捷開發調整式規劃的關連。規劃的目的不是為了得到一個巨細彌遺的計劃讓我們照表操課，而是指引一個達到目標的概略方向，然後因應專案實際現狀來調整計劃，來使我們不致迷航。基於這樣的觀念，運用 <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD（測試驅動開發）</a>剛好可以提供對專案進行直接及穩定的觀察。</p>
<p>TDD 改變我們對解決問題的假設，不假設用什麼方法來解決問題，而是假設問題情境來思考各種可能的方法，並發展出最經濟的解決方案。假設方法如何解決問題並不是不好，只是這樣很容易讓開發者把他所熟悉的方法當成黃金錘，但最後所開發出來的軟體卻不見得符合使用者實際的需要，而且通常要花費很長的時間才會發現以上的落差，因此不會有足夠時間和資源來符合使用者的需求。</p>
<p>如果能儘早驗證開發的成果是否符合實際的需要，開發者就可以在早期得到使用者的回饋，進而調整努力方向來改善開發成果。傳統的開發方法沒有辦法做到早期回饋，是因為使用者要等到軟體開發出來才能接觸到系統，而且通常他們缺乏軟體開發的專業知識，所以在這之前他們是很難給予開發者有效的回饋。TDD 的開發思維則是促使開發者從思考軟體的使用情境出發，不要太早接觸繁複而細節的設計或實作，而是因應實際的需要而定義出界面規格，然後依據這些規格來決定該如何驗證問題能夠被解決。</p>
<p>因此，TDD 可以直接而穩定的在早期觀察開發狀態，提供設計演進的基準。這樣的基準可以讓開發者在開發過程中，直接面對目標而開發系統而不致迷航。也就是因應現實問題情境的需要，開發者未必有足夠的時間與心力來把設計做到盡善盡美，而是嘗試定義出最主要的功能需求，先採用最簡單的方式來滿足它們，然後再視使用者回饋的實際需要增添或修正功能，必要的時候甚至可以進行重構來維持設計簡潔與完整。換言之，TDD 是用來使開發者面對目標，讓開發範圍不要無謂擴張的一項有力工具。</p>
<h4>延緩設計的決策</h4>
<p>然而，當開發者採用了 TDD 的開發模式之後，是否正意味著我們儘快將使用者需要的功能實作出來，並不需要進行太多的設計工作，是否代表設計對使用 <a href="http://en.wikipedia.org/wiki/Extreme_Programming">XP 實務</a>的開發者來說是不重要的呢。但依照同人自身的經驗來看，對於使用 XP 實務的開發者而言，設計並非不重要，而是留下為實際的問題改進設計的彈性。</p>
<p>TDD 並非不做設計，而是把做更周詳的設計的時間延後到可以得到更佳設計決策的時候。或者更根本地來說，TDD 本身就是一種設計手法；而不是因為它以寫測試案例開始，而就把它當做開發的測試過程，<a href="http://www.lifeparty.idv.tw/blog/archives/2669">這樣的誤解反而違反 TDD 的基本精神</a>。</p>
<p>就設計的觀念來看，設計概念的完整性會直接影響設計的良窳。因此開發者應該盡全力來找出解決問題最重要的概念，同時隱藏或略除不必要的實作細節，來使設計更容易了解與實作。這也就是設計關鍵在於抽象化的道理，但問題是在對問題認識未盡全面以及成本或時程的限制，開發者通常沒辦法在第一時間找出解決問題最適當的核心概念。</p>
<p>因此，TDD 在還沒寫實際的程式之前，先撰寫測試案例。其所關注的問題並不是有效率的測試，而是務實的設計。先以測試案例的方法來識別出系統的大致輪廓，目的是以解決問題為前提，把問題的範圍限制在開發者可以全局掌控的情況下發展解決方案。而不是為了解決方案的堅持而使問題發散，最後反而使問題失焦而終致失控局面的發生。</p>
<p>如此，縱使軟體開發的變化是難以預測的，但只要每一次的變化都可以將廣大的可能性，限制在某一部份，那麼開發者就可以在系統的穩定與彈性之間維持良好的動態平衡；既不會讓需求的變化造成設計的崩壞，也不會因為技術的限制而造成設計的僵化。</p>
<p>穩定的設計可以在環境改變的情況下，不致使系統失去控制，彈性則是可以適應需求的變化而改進系統的設計。期待設計在一開始一次到位，這通常是不切實際的期待，還不如面對現實，先用簡單的方式滿足需求，然後隨著對問題的更深入理解，自然而然地演進出可以適應變化的設計。</p>
<p>這樣的觀念是把軟體開發的焦點放在系統邊界，然後隨著環境變化而逐步演進核心的設計，與傳統機械觀點的隱喻所不同的是，軟體開發不是努力去製造一些東西，而是運用生物演化觀點的隱喻：軟體開發是為了改變一些事情而努力。TDD 與 Refactoring 的搭配，正是促成軟體開發演化出複雜適應性以適應變化的實務方法。它們可用來避免軟體設計求道之過，所謂「<a href="http://zh.wikisource.org/wiki/%E6%97%A5%E5%96%BB">道可致而不可求</a>」不去強求而自然得到，才是真正的致呀。</p>
<h4>提早整合的行動</h4>
<p>其實軟體開發專案要把穩方向是很困難的，溫伯格認為主要的原因多半是管理者介入無效的管理作為；沒辦法掌握好「動作要小，行動要快」的原則，結果更增加專案的複雜度與風險，使得問題更加難以處理。</p>
<p>因此，如果使用 TDD 與 Refactoring 這兩項實務，可以讓我們具體地用測試案例來直接而穩定地觀察開發成果，運用簡單的設計來解決問題，又可以在必要的時候施重構來改善設計，以增加適應變化的彈性。那這樣還有沒有可能沒辦法掌握好設計演進的節奏呢？同人認為唯一的可能就是開發者沒有提早整合的行動，例如沒有在早期接受回饋以調整測試案例與重構，使得行動太慢，動作太大。</p>
<p>為什麼開發者會沒有提早整合呢？理論上，當開發者開發的程式完成 TDD 的測試程式之後，照理要進行清理程式碼的動作。比如說進行重構來去消除程式碼的重覆性或使程式碼看起來更簡潔而易懂。這樣可以讓程式碼在每一次的修正之後，都還是最乾淨的情況下，所以是不大可能會增加程式碼複雜度而造成未來難以維護的問題。</p>
<p>然而，在考量專案實際的問題下，開發者不見得每一次都會有足夠的時間來整理他的程式碼，使之形成良好的程式寫作風格與結構。而且管理者也很難知道開發者到有沒有力行這樣的原則，除非能夠對每一支程式來進行 <a href="http://en.wikipedia.org/wiki/Software_peer_review">Peer Review</a>，否則只有「完成功能之後必須清理程式碼」的說法，而沒有為提昇程式碼品質而在每支程式交付時，提供改善回饋的具體措施，對專案其實並沒有太大的助益。</p>
<p>可能有人會認為<a href="http://en.wikipedia.org/wiki/Pair_programming">搭檔編程</a>的實務，就是讓每一次的程式開發都提供回饋。基本上同人並不反對這樣的說法，但要這樣做必須注意開發團隊的文化是否能夠支持這樣的做法。</p>
<p>同人以前曾有專案成員調動到使用搭檔編程的專案團隊，雖然看起來搭檔編程似乎讓她能力有所成長，但我也發現到她也出現適應不良的現象而心生抗拒，而當同人與他當時的主管當時的關心，也很難讓他願意分享自己的心情。由此看來，似乎還是有人習慣自己一個人寫程式，而不喜歡由兩個人共同開發一支程式，而且開發資源的分配者也不見得能夠支持這樣的觀念。</p>
<p>當然，要針對每一支程式做到 Peer Review，在實務上還是有很大的困難的。同人認為問題並不是 review code 要花費多少時間，而是專案需不需要針對程式碼進行儘早的回饋，以在最適當的時機採取最適當的行動？這其實是取決於專案願意花費多大的代價來提昇軟體的品質，不然當品質不合乎需求時，專案所節省下來的預防與檢驗成本將會為造成更大的失敗成本。</p>
<p>要落實提早整合的行動，專案團隊每天早上的 <a href="http://en.wikipedia.org/wiki/Stand-up_meeting">Daily stand-up</a> 會議與採用 <a href="http://en.wikipedia.org/wiki/Daily_build">Daily build</a> 持續整合的機制，是讓開發團隊的反應能力可以「與時俱進」的回饋活動。就像同人在分享會所分享的實務，在 Daily stand-up 會議得到開發實際碰到的問題，其實是幫我們識別關鍵設計概念的機會。由於過去問題尚未出現或對它們還不太明瞭，所以我們不需要或沒辦法進行設計的深入考量。而在 Daily stand-up 會議中，我們可以及時得到用來演進設計的資訊，並討論如何在後續的計劃中調整設計。</p>
<p>至於 Daily build，每天都會整合出可以實際運作的軟體。在 build 軟體的過程中，會自動執行 TDD 的自動化測試，以確保系統功能都是正常的。如果在 build 的過程中發生問題，馬上會立即通知相關的開發者立即解決問題。這樣可以在每天都讓每個開發小組都能密切地保持緊密的溝通與整合，發現問題立即處理而不需要等問題擴大之後才動大刀。</p>
<p>Daily stand-up 會議與 Daily build 的活動，讓每天都持續溝通與持續整合，每次都讓專案都朝向目標前進一小步，更重要的是，讓成員與時俱進地掌握設計演進的節奏！</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/2784"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/2784/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>再談技術經理當教練</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/2634</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/2634#comments</comments>
		<pubDate>Thu, 31 Dec 2009 10:31:03 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=2634</guid>
		<description><![CDATA[技術經理當教練如果對公司是不好的徵兆，問題應該還是出在領導上，誠如同人過去發表過的文章所講的：強將手下無弱兵，但也不會有強將。沒有辦法訓練培養人才的教練，還是因為技術經理不諳教練之道呀！]]></description>
			<content:encoded><![CDATA[<p><a href="http://scmteamwork.blogspot.com/">MaoYang</a> 兄看到我分享〈<a href="http://www.lifeparty.idv.tw/blog/archives/2563">技術經理的教練角色</a>〉之後，他在<a href="http://www.plurk.com/p/36po20">噗浪河道上</a>回應他對我文章觀點的看法。他說：</p>
<blockquote><p>我常在做的 "教練" 工作大部分是在講一些基礎的東西與衍生的技術, 但是倒沒有想過要將團隊變成 "一致性" , 試想, 你身為經理確發現實作的工程師缺乏某些觀念時, 你不得不著急,但是這種狀況出來的時候, 產品也開始出現許多問題, 這是技術經理面臨最大的挑戰。但是當技術經理開始當 "教練" 已經離開工程師角色一段時間, 這又是另一個挑戰</p></blockquote>
<p>同人很高興 MaoYang 能夠針對這個主題提出討論。對於他所提到的問題，我常看到的是技術經理不能因材施教，所以究竟來看也是身為教練本身指導的彈性不足，也是多樣性的問題，尤其在軟體開發專案更為常見。</p>
<p>而且有時候工程師不是不懂那些概念，而是他們碰到一些技術經理不重視或忽略的問題，但如果沒辦法幫他們解決那些問題，如何讓他們接受那些觀念。教練就只會流於說教的自說自話。所以是管理能力的不足而非技術，也是我文章著墨於領導觀點重於技術觀點的主要原因。</p>
<p>對於領導，MaoYang 認為最好的領導是當顧問而不是教練；他提到工程師可以自己發現問題，來請教 "顧問" ，當然如果工程師都看不到問題，那麼就另當別論。MaoYang 還提到他很欣賞上次 <a href="http://www.wretch.cc/blog/kojenchieh">David Ko</a> 在<a href="http://www.lifeparty.idv.tw/blog/archives/2114">敏捷開發分享會</a>提到的經驗；團隊主動提出要使用 Scrum，這時候身為經理的 David 只要做順水推舟的工作即可。</p>
<p>不過同人倒是認為，David Ko 的經驗是可遇不可求的。同人的經驗顯示，在台灣的軟體開發機構，是很少經營者有願意改變的胸襟與勇氣，即使有些老闆在口頭上說改革，但骨子裡卻是很畏懼改變而使所謂的改革只是流於表相化。</p>
<p>MaoYang 提到他在職場現實看到的一個現象；他說我在文中提到教練最好可以不給答案，而是提出問題讓工程師去思考。但是他在現實職場看到的是一堆人在揣摩老闆在想什麼？要怎麼做，老闆才會滿意？因此有時候他反而不太喜歡這樣的領導模式。同人覺得 MaoYang 這段說到重點了，但為什麼會形成這樣的企業文化呢？</p>
<p>MaoYang 說他覺得在中國人的企業都會有這種問題，這是為什麼 "雍正王朝" 被列為某些企業的管理教材。在雍正王朝裡面一堆這種範例，沒有正確答案，正確答案在主子的腦袋裡面。 這種文化要改，可能是領導者的腦袋要先改。</p>
<p>然後 MaoYang 還分享後來他想到他說技術經理下來當教練是不得不，意思是說理論上應該不用走到這一步，問題出在當初找人時，沒有嚴格把關，沒有找到對的人。他還提到 《<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010387385">Peopleware</a>》 裡面也有講要如何 interview 工程師，所以《<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010202911">從 A 到 A+</a>》裡面也有講企業要成功，要找到對的人。所以他認為技術經理當教練的徵兆對一家公司其實是不太好的，技術經理應該去看前瞻的東西，而不是當一名 "教練"。</p>
<p>其實同人很同意找到對的人來做事的想法，但事實上這卻是不容易做到的，尤其是軟體開發工作的專案，更難以找到對的人來做事。這種困難包括兩種情境，一種是找不到合適的人才來執行任務，另一種是把真正的人才放到不正確的任務上。</p>
<p>第一種情境雖然很常看到，但經常也可能是技術經理沒辦法慧眼識英雄或因材施教，而使好的人才淪為的犧牲品。在這種情狀下，其實問題不在找不到人才而是經理人本身領導或管理的問題。寫到這裡，我想到溫伯格在《<a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010411034">第一級評量</a>》講的一句話：沒有不好的士兵，只有不會帶兵的將領。</p>
<p>所以技術經理當教練如果對公司是不好的徵兆，問題應該還是出在領導上，誠如<a href="http://www.lifeparty.idv.tw/blog/archives/433">同人過去發表過的文章</a>所講的：強將手下無弱兵，但也不會有強將。沒有辦法訓練培養人才的教練，還是因為技術經理不諳教練之道呀！</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 525px; width: 1px; height: 1px;">http://www.books.com.tw/exep/prod/booksfile.php?item=0010202911r</div>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/2634"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/2634/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java 泛型複雜嗎？</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/2328</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/2328#comments</comments>
		<pubDate>Wed, 16 Dec 2009 10:53:07 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=2328</guid>
		<description><![CDATA[表面上看起來好像實作泛型可以讓某一段程式碼重複使用，但 Java 在泛型的限制，也增加他重構程式碼的困難度與複雜度。這麼說來，假如石頭成的想法是正確的，用 Java 的泛型來重構程式碼，只會讓程式員沒事自討苦吃。然而，同人在仔細研究他的程式碼之後，發現可以用更簡潔的方式來使用 Java 的泛型。]]></description>
			<content:encoded><![CDATA[<p>石頭成在〈<a href="http://blog.roodo.com/rocksaying/archives/10914229.html">與 metavige 和 alexchen 對話 Java 語言</a>〉這篇文章中，直言他對 Java 語言泛型的批評：</p>
<blockquote><p>我不認為 Java 讓我們「慢工出細活」，我覺得它帶來的是「冗餘的複雜性」。就算以 C++ 的觀點來看 Java 程式碼，我仍覺得 Java 程式碼有許多不必要的複雜度。Java 把類別變成施加在程序員身上的束縛，而是不是幫助我們進行抽象化資料處理的工具。</p>
<p>我個人認為，所謂「更強化的靜態型態」是跟 C++ 樣板相比， Java 泛型比起 C++ 樣板是在走回頭路。就我到目前為止的 Java 使用經驗來看，我幾乎以為泛型只是 Java 專門用來重新設計容器類別的特殊語法。在那以外的場所，你大概不會想用泛型來重構你的程式碼。</p>
<p>metavige 就說會想用 Strategy Pattern 來重構我在〈<a href="http://blog.roodo.com/rocksaying/archives/10890551.html">從 C++ Template 到 Java Generic，一步一步來</a>〉舉的例子，而不會用泛型。但是泛型難道不是用來處理這個問題的直覺想法嗎？ Java 沒有足夠理由說服我們不要用泛型來做，但是用泛型來做&#8230; 呃，似乎更困難。 </p></blockquote>
<p>石頭成用<a href="http://en.wikipedia.org/wiki/Generic_programming">泛型</a>來重構程式碼，是不是處理他的問題之直覺想法？我想石頭成比較偏好動態型態語言的自由，比較不欣賞「更強化的靜態型態」的做法。或許是因為 C++ 用 template 實作不會受到參數型別類型的限制，自然會讓他比較想用泛型來重構程式，以去除資料型態與演算邏輯的相依性。然而，看過石頭成所舉的實例，同人認為用泛型來實作的想法未必是直覺的做法。</p>
<p>表面上看起來好像實作泛型可以讓某一段程式碼重複使用，但 Java 在泛型的限制，也增加他重構程式碼的困難度與複雜度。這麼說來，假如石頭成的想法是正確的，用 Java 的泛型來重構程式碼，只會讓程式員沒事自討苦吃。然而，同人在仔細研究他的程式碼之後，發現可以用更簡潔的方式來使用 Java 的泛型。不過，還是讓我們先來看看石頭成的程式碼：</p>
<p><u>Cx.java</u></p>
<pre class="brush: java; tab-size: 2">
public class Cx&lt;DataType extends IDataType&lt;ReturnType&gt;, ReturnType&gt; {
	private DataType data;

	public Cx(DataType v) {
		data = v;
	}

	public ReturnType getData() {
		return data.value();
	}
}
</pre>
<p><u>IDataType.java</u></p>
<pre class="brush: java; tab-size: 2">
public interface IDataType&lt;ReturnType&gt; {
	     public ReturnType value();
}
</pre>
<p><u>N.java</u></p>
<pre class="brush: java; tab-size: 2">
public class N implements IDataType&lt;Integer&gt; {
	private Integer n;

	public N() {
		n = 0;
	}

	public N(Integer v) {
		n = v;
	}

	public Integer value() {
		return -n;
	}
}
</pre>
<p><u>M.java</u></p>
<pre class="brush: java; tab-size: 2">
public class M implements IDataType&lt;Integer&gt; {
	private Integer m;

	public M() {
		m = 0;
	}

	public M(Integer v) {
		m = v;
	}

	public Integer value() {
		return m * 10;
	}
}
</pre>
<p><u>S.java</u></p>
<pre class="brush: java; tab-size: 2">
public class M implements IDataType&lt;Integer&gt; {
	private Integer m;

	public M() {
		m = 0;
	}

	public M(Integer v) {
		m = v;
	}

	public Integer value() {
		return m * 10;
	}
}
</pre>
<p><u>Main.java</u></p>
<pre class="brush: java; tab-size: 2">
public class Main {
	public static void main(String[] args) {
		N n = new N(1);
		Cx&lt;N, Integer&gt; cn = new Cx&lt;N, Integer&gt;(n);
		System.out.println(cn.getData());

		M m = new M(1);
		Cx&lt;M, Integer&gt; cm = new Cx&lt;M, Integer&gt;(m);
		System.out.println(cm.getData());

		S s = new S("hello");
		Cx&lt;S, String&gt; cs = new Cx&lt;S, String&gt;(s);
		System.out.println(cs.getData());
	}
}
</pre>
<h4>問題</h4>
<p>石頭成認為他的程式存在兩個問題。第一個問題是原來 N、M、S 三個類別沒有繼承關係，但為了符合 Java 泛型的特性，在重構之後這三個類別卻實現了同一個界面。石頭成原來認為用泛型解決演算法重複問題時，應該依然保持那三個類別之間無關性，但重構之後卻發現 Java 的泛型並不能保持那三個類別的無關性。雖然在這個範例中影響不大，但他還是認為 Java 在泛型方面的表現，只能算是勉強及格。</p>
<p>第二個問題是他不知道如何在 Cx 中增加預設建構子，來初始化 data 成員變數。如果 Java 直接 new 一個參數化型別的實例，在下面的程式碼的第 5 行的地方，會出現「Unexpected type」的編譯錯誤訊息。但在 C++ 的 template 中，這種寫法卻是可以被接受的，令他實在是不能理解，JVM 為什麼不能自己反射參數化型別來建立物件實體，而要用這個限制來難倒程式員。</p>
<pre class="brush: java; tab-size: 2">
public class Cx&lt;DataType extends IDataType&lt;ReturnType&gt;, ReturnType&gt; {
  private DataType data;  

  public Cx() {
    data = new DataType();
  }  

  public Cx(DataType v) {
    data = v;
  }  

  public ReturnType getData() {
    return data.value();
  }
}
</pre>
<p>要對石頭成提出的這兩個問題有比較精確的理解，不能不對 <a href="http://en.wikipedia.org/wiki/Concept_%28generic_programming%29">concept 的概念</a>有所認識。在泛型程式設計中，concept 指的是一組型別，它們提供某些語法與語意操作的支援。concept 與抽象基礎類別有關，但 concept 並不需要子型別的關係。</p>
<p>在 C++，concept 這個術語只是簡單地命名並簡單描述參數型別的需求，而符合此 concept 的型別，一般被稱為 model。我們不能用程式語言明確地表達 concept，只能表示某種參數型別的物件會嘗試執行什麼操作，以及期待的工作結果；也就是讓它可以正常的編譯。一般來說，Java 及 C# 的泛型與 C++ 的泛型有點像，只不過它們用 interface 來扮演 concept 的角色。</p>
<p>但這樣一來，符合的參數型別就只能是實作某個明確的界面，當然 concept 顯然會比 interface 更有彈性，因為 concept 可明確代替一組型別，而不只是一個實作某 interface 的類別；而且運用隱式地定義自動 concept，可以讓參數型別同時使用內建型別或其它為了非特殊用途的型別。</p>
<h4>相依性</h4>
<p>從以上的觀念來看，用 C++ 的 template 來實作泛型程式設計，的確比 Java 的 interface 有更大的彈性。不過，即使是使用 concept 來表示參數型別，在這組支援泛型實作的型別中，其實也必須支援 concept 定義的基本操作。就廣義來說，model 必須依存於 concept 所定義的界面。相對於<a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">物件導向的 LSP</a> 原則，子類別應該可以替換父類別，concept 與 model 之間也有類似的關係。如果 Cb 是 Ca 的強化 concept；也就是定義更多延伸 concept 所需的操作，那麼 Cb 的 model 則必然是 Ca 的 model。</p>
<p>於是，我們看到石頭成的程式，N、M、S 都實作相同的界面 IDataType，這將不會是個問題。其實改動 N，並不會影響到 M、或是 S，因為三者並不直接相依，除非它們共同引用的界面變動才會影響到其它實作相同界面的程式。事實上，界面完全不牽涉到任何實作，除非界面定義得不夠完整，石頭成所擔心的問題才會發生。但如果是這樣，那將不是程式語言的問題，而是設計本身的問題。</p>
<h4>複雜性</h4>
<p>當然，我們也不能否認石頭成提到的另一個問題，是實際存在的事實。Java 使用 interface 來實作泛型確實有比 C++ 的型別 concept 有不足之處。以 interface 來抽象化參數型別沒辦法做到 default construction 這種型別 concept，因為它不是類別，沒有辦法自己生成物件實體，必須要靠外界呼叫者初始化參數型別物件，再傳給泛型物件才能正常工作。</p>
<p>再加上 Java 無法在執行期的時候取得參數型別的關係，我們無法直接以反射機制產生出參數型別的建構式來產生物件實體。雖然繞個圈，我們還是可以用另一種反射方式達到目的，但這樣會使得程式碼變得更複雜而且難以理解，實在是會令人望之卻步。那麼使用 Java 泛型，有沒有比較簡單的方法可以解決這個問題呢？</p>
<p><u>C++</u></p>
<pre class="brush: c++;">
DataType data; // default construction
</pre>
<p><u>Java</u></p>
<pre class="brush: java;">
//data = new DataType();
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
data = ((Class) pt.getActualTypeArguments()[0]).newInstance();
</pre>
<h4>解決方法</h4>
<p>其實解決的方法並不難，雖然我們在 Cx 仍然很難用參數型別反射預設建構式來建立物件實體，但如果你對同人過去發表的〈<a href="http://www.lifeparty.idv.tw/blog/archives/449">降低資料存取的複雜性</a>〉還有印象的話，你可以從這篇文章找到解決石頭成問題的方向。我們可以在這篇文章看到，在還沒使用 Java 的泛型之前，UserDataAccessorImpl 有預設建構子可供初始化 UserDataAccessor 的物件實體，但使用 Java 的泛型重構之後，泛型版本的 HibernateDataAccessor 卻只提供指定參數型別 BizObject 的 Class 建構式。所以使用同樣的原理，我們應該也可以解決石頭成的第二個問題。</p>
<pre class="brush: java; tab-size=2">
	public Cx(Class&lt;? extends IDataType&lt;ReturnType&gt; &gt; dataTypeClazz) throws Exception {
		data = dataTypeClazz.newInstance();
	}
</pre>
<p>或許有人可能會說我改變了石頭成第二個問題的需求，他要的不是以 DataType 的 Class 當參數的建構式，而是不需要任何參數的預設建構式。但其實希望在 Cx 加入預設建構式並不是需求，而是為了解決問題的需求所做的假設，要認清需求我們必須質疑存在這個假設背後的問題。</p>
<p>當我們想到 Cx 為什麼需要預設建構式的時候會發現，有些時候因為要<a href="http://www.lifeparty.idv.tw/blog/archives/271">跨越遠端界面呼叫的藩離</a>，可能沒辦法由呼叫者產生參數型別的物件傳給 Cx，而要由 Cx 自己初始參數型別物件。但通常傳入參數型別物件的 Class 是可行的，因為運用 Java 的反射機制，傳遞 Class 就好像傳遞 String 一樣簡單。</p>
<h4>更直覺的做法</h4>
<p>寫到這裡，石頭成的問題應該是解決了。不過回到這篇文章同人一開始所提到的，石頭成所舉的實例，我認為用泛型來實作的想法未必是直覺的做法。那麼同人認為更直覺的做法是什麼？其實我不會完全用泛型來解決石頭成的問題，而是運用多型來封裝演算法的差異性，再搭配泛型來強化參數型別的一致性。這樣我只需要修改石頭成的 Cx 類別與 Main 主程式碼，如下面這段程式碼所示，同人認為是更為簡單而直覺的做法。</p>
<p><u>Cx.java</u></p>
<pre class="brush: java; tab-size: 2">
public class Cx&lt;ReturnType&gt; {
	IDataType&lt;ReturnType&gt; data;

	public Cx(Class&lt;? extends IDataType&lt;ReturnType&gt; &gt; dataTypeClazz) throws Exception {
		data = dataTypeClazz.newInstance();
	}

	public Cx(IDataType&lt;ReturnType&gt; data) {
		this.data = data;
	}

	public ReturnType getData() {
		return data.value();
	}
}
</pre>
<p><u>Main.java</u></p>
<pre class="brush: java; tab-size: 2">
public class Main {
	public static void main(String[] args) {
		N n = new N(1);
		Cx&lt;Integer&gt; cn = new Cx&lt;Integer&gt;(n);
		System.out.println(cn.getData());

		M m = new M(1);
		Cx&lt;Integer&gt; cm = new Cx&lt;Integer&gt;(m);
		System.out.println(cm.getData());

		S s = new S("hello");
		Cx&lt;String&gt; cs = new Cx&lt;String&gt;(s);
		System.out.println(cs.getData());
	}
}
</pre>
<p>上面這一段程式碼，將類別 Cx 當中的 data 的型別，由 DataType 參數型別改成 IDataType 的多型界面。這樣一來，data 的抽象概念就從參數型別轉移到多型界面，此界面封裝了不同的資料型態行為的抽象概念。如此一來，Cx 可減少了一個參數型別，程式碼也變得簡明易懂。從 Main 呼叫端的程式碼就可以發現，少了一個參數型別，程式碼也變得簡潔許多。</p>
<p>這段程式碼也讓我們發現泛型可以強化多型界面的資料型別。假如沒有泛型，我們就只能在 DataType 的 value() 回傳值定義成可以包容各種資料的型別；例如 String 或 Object，然後再運用資料轉換或強制轉型的方式取得我們需要的資料格式，但這些方法很容易出錯，而且會造成程式開發不小的負擔。當我們運用泛型來強化多型界面的型別，程式員就不用在這方面傷腦筋了，而且設計的完整概念也更容易維持。</p>
<h4>泛型與多型的差別</h4>
<p>就設計的觀點來看，參數型別並不是真正的實體型別，如果沒有 default construction 的 concept，我們沒辦法拿它來產生任何實體型別的實體。多型的解決方案，是運用型別來抽象化型別，與泛型用型別的 concept 來抽象化型別是不同的抽象觀點。後者如果想在 Java 的泛型來取代多型的解法，其實是會讓程式員遇到很多麻煩的。</p>
<p>其實即使換成 C++，同人不會把不同資料型態以 DataType 參數型別抽象化。雖然 C++ 的 template 真的很有彈性，但那並不意味著使用它不需要為這些彈性付出代價。例如，使用 C++ template 編程，在除錯上或處理編譯的錯誤會比沒有使用 template 還要困難許多。</p>
<p>尤其是 C++ template 的編輯錯誤訊息，常讓人搞不清楚錯誤在那裡，往往要花費很大的工夫才找到程式員無心犯下微不足道的錯誤。所以， C++ 的 template 給予程式員相當大的彈性，但過度地使用它，也很容易讓程式碼產生不必要的複雜度。</p>
<p>依同人的經驗顯示，許多表面上泛型似乎可以用來解決的多型問題，但一旦用泛型來解，常會因為抽象化層次不同的隔閡而使問題更為複雜。</p>
<p>泛型的原理是引用 concept 來代表各種可供參數化的型別，而多型則是使用抽象類別或界面來封裝具體類別。兩者的抽象化的觀點不一樣，一種是型別的集合對個別型別的關係，另一種則是型別與型別的關係。</p>
<p>前者的關係我們稱為某些型別是某個 concept 的 model，而後者的關係則是型別之間的一般化或實現關係。兩者在本質上的概念是不一樣的，因此當我們想用 concept 來代替 <a href="http://en.wikipedia.org/wiki/Inheritance_%28computer_science%29">inheritance</a>，或是用 inheritance 來取代 concept，最後都必然會讓我們遇到實作與概念上的隔閡。</p>
<p>當一個類別 A 使用到泛型類別 B 時，我們就必須指明使用 B 所需要的參數型別，要不然就必須由使用到類別 A 的類別 C 指定需要的參數型別。所以如果類別 A 想要不侷限在某種資料型別，那麼使用泛型類別 B 的代價就必須是讓類別 A 也變成泛型物件。所以大量使用泛型的結果，會使你一層又一層地使用參數型別，這當然是比多型複雜許多。</p>
<p>此外，以泛型來取代多型更麻煩的是，不同參數型別的泛型物件是完全不同的類別，它們不像多型可以用同樣的方式來處理不同資料型態。所以雖然表面上泛型省去繼承類別或實作界面的工作，看起來比多型的解決方法有更大的自由度。但這也意味著泛型可能會缺少對問題語意封裝抽象概念，只是站在實作觀點以一致性的方法來滿足需求。</p>
<p>程式員不該為了貪圖一致性而忽略多樣性，而是應該按照實際的需要來解決問題。所以重點不是 Java 泛型是否複雜，而是我們能不能運用設計使它變得更簡單。語言的限制未必是加諸在程式員身上的束縛，而可能是讓我們進行思考以發揮設計創意的機會呀。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/2328"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/2328/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>簡單，複雜世界的致勝之道</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/982</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/982#comments</comments>
		<pubDate>Fri, 17 Jul 2009 11:31:39 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=982</guid>
		<description><![CDATA[世界愈複雜，我們就更需要簡單。簡單讓我們看清楚事物的脈絡，掌握重點，以協助做出選擇，並在適當時機採取行動。然而，簡單其實是困難的，因為要做到簡單，意味著我們必須清楚事物的全貎，行動必須要更有原則。尤其是在複雜多變的環境當中，簡單不能只靠直覺，而是有紀律的思考與行動。 那麼，用有紀律的思考與行動，以做到簡單，我們該怎麼做呢？前一陣子，同人閱讀了《越簡單越有力量》，我覺得這本書的觀念與方法，剛好可以提供我們複雜世界簡單之道的思考方向與指引。 這本書是作者將自己的公司投入「尋求簡單之道」（search for a simple way）專案的研究心得。這個專案是一項由北伊利諾大學共同贊助的五年計劃，目標是為了研究美國企業資訊時代的規劃與設計工作。研究結果發現企業在改善工作環境、符合客戶與股東期望方面，已有長足顯著的進步；至於如何讓工作各項選擇透明化，進而提供必要的工具與資訊，以提供員工績效，卻相形見絀。 這樣的結果讓我們體會簡單之道的重要性，但什麼是簡單之道呢？本書作者認為簡單就是一種資訊革命，是為了化複雜而明確，也就是製造正確的指令。這些指令照樣鼔勵全面改變、實驗、概念融合、發明、學習；而其背後的大原則，是要為執行工作者釐清問題與真義。 複雜面向的四個主要來源 那麼，為什麼我們的工作總是那麼複雜？本書提到根據「尋求簡單之道」的研究結果顯示，造成複雜面向有四個主要來源，依重要性往下排列依序為： 沉重的資訊負荷：有八成的員工與六成的主管找不到、或無法轉化必要資訊，以做出決定。 沒效率的溝通：每個人都認為他們盡力去努力溝通，但大部分溝通都缺乏原則。 目標宗旨不明：眾多目標欠缺目標整合，整合目標不可缺少領導者的配合。此外，嚴謹的目標設定遮蔽真正授權，掩飾公司內部的缺乏互信。 變革欠缺整合：高層主管與員工對整合觀點的懸殊態度，對於整合，領導者關心的焦點是管理、控制與協調的工具；而員工關切的重點是有利個人決策的工具，執行工作者的觀點常會受到不平等的對待。 因此，我們應該如何發揮簡單的力量，減少我們工作的複雜性呢？本書提出簡單必須掌握兩個必要前提，首先必須改變對時間的運用方式，讓我們用更有效率的方式來運用時間。其次管理者應當逆向思考，以使用者為中心，也就是依員工的需要來規劃工具、流程與資訊。此外，簡單之所以有效，是因為兼顧人性與常識兩大原則。本書提到任何以企業邏輯主導變革的失敗，是因為違反了簡單的這兩項原則，以致於沒辦法扭轉人們的行為與習慣而功虧一簣。 掌控時間 身為知識工作者，我們該如何更有效率地運用時間呢？書中提到要提高工作效率，必須通過「了解」、「感覺」、「運用」、「執行」、以及「達成任務」這五項基石。針對每一項建立明確性，將強化你對時間的分配運用。 五項基石如何建立明確性呢？我們必須「了解」那些事真正重要，每一個人都必須弄清楚，什麼能帶來最大效益？因為我們可能還沒考慮周詳，就開始要求別人開始著手。我們也必須考慮並準備這項過程能帶來的「感覺」，沒有人做決定絲毫不帶感情。因為考慮怎麼辦的過程，必然有情緒在裡面。「運用」則是我們必須專注在需要派上用場的工具及資源，這是大家完成工作的方法。因為即使大家目標相同，但許多員工卻缺乏必要的工具或訓練。 「執行」是我們必須建立並控制期望，充分了解程序及後續步驟，是最起碼的條件。因為當命令與控制遭到排斥，許多經理人便喪失了澄清目標的能力。所以要讓每一份子知道，誰該在什麼時候擔負什麼責任。「達成任務」則是我們必須對我們想達成的目標，建立可以傳遞的觀點，對於成功的定義，員工與公司看法不同，如果把行為列入考慮，就比較能體會成功的結果。因為人們往往焦頭爛額同時進行多個案子，卻不曉得成功之後又將如何。 規劃 本書提到不論計劃規模的大小，規劃者的角色就是為了塑造成功的對話。換句話說，規劃我們必須整合計劃中的每一個小節，讓討論充分發揮效益，以確保眾人的時間、精力都沒有被浪費。如何做呢？書中運用五項基石發展出兩項工具： 了解，感覺，執行：每個人藉以經過討論，弄清楚自己的角色與行為。 運用以達成任務：進一步完成工作。 這兩項工具，目的是幫我們整理思緒。它們並不是用來做表面文章，而是提供支援，改變我們支配時間的方式；讓我們把想法或計劃為輕重有序，條理分明的對談。 行為溝通模式 本書提到在研究當中，觀察人們在採取行動之前，需要怎樣的資訊。結果研究發現決定採取任何行動的背後，必然隱含下列五個問題： 這和我的工作有何關係？每個人要關切、要注意的事情太多了，如果我們把注意力擺在所有可能有關的事情上，那將一事無成。如果我們能把我們所說的事情，與大家目前利用時間、精力的方式做個聯繫，那就真的值得一提。 我究竟應該採取哪些步驟？這不是命令與控制，而是讓期望透明。我們必須充分傳遞下列問題的答案：緊接著的下一步該做什麼？整個流程包括那些環節？誰該負責這個步驟？如果責任轉移，會採取什麼方式告知？ 我的表現將如何評估？結果如何？除了讓員工明確了解自己工作的成效、成功的定義、多久可以得到主管評語等討論之外，還必須了解任務成敗所導致的結果。 有什麼工具與支援可供使用？大多數的人不是缺乏必要的輔助工具，就是不懂得如何利用。如果能夠連接工作目標和可用的工具，不管我們要做什麼，力量將十分可觀。 對我及我們而言，有什麼意義？正式的鎬賞或獎勵不見得是唯一的選擇，其它如減輕壓力、提高樂趣、加強團隊精神、以及有更多時間與家人相處也是可以激勵員工的辦法。 如果我們都能致力回答這五個問題，那麼任何談話都會不費吹灰之力，迅速落實為行動；你將馬上獲得眾人的支持與理解，於是會發現要改變時間運用的方式，其實並不困難。 行為溝通模式還能幫我們聆聽與過濾訊息，刪除不必要的資訊以擷取菁華。依據以上五個問題，任何談話、會議、電子郵件都應明確過濾掉未提及「與我做的事有關」、「後續步驟明細表」、「期望」、「能力」、「回報」的資訊。 以故事來彙整融合 改變對時間的運用方式，我們需要架構嚴謹的思考與溝通，意味著在採取行動之前，必須好好地思考，用來整理與釐清一切問題。然而，如果我們要釐清問題的對象，是在工作團隊以外的廣大對象，這時就很難用五項基石的概念與他們溝通。本書認為此時必須運用說故事的手法將五項基石融入一個引人入勝的大綱。 所有的故事都包括了衝突、轉變、高潮、結尾四個階段。應對到企業的故事則是企業改革前提開始，意味著員工必須對現行方式有所不滿，才會有動機想採用另一種模式。接著表揚成就，檢討失敗，企業的轉捩點就是當企業慶賀成功、檢討教訓時；在這個時刻，讓員工了解目標達成多少，該如何改進。 企業故事的高潮，是企業今年度成功目標達成之時，把故事架構放在策略方案上，有助讓人們窺見其它架構無法呈現的漏洞。最後由使命、願景、價值觀來結尾，讓員工知道為何而忙，不過必須注意不要只顧談高調而忽略提供必要工具、流程與支援，讓員工能順利發揮潛能。 以使用者為中心 本書認為簡單化的公司是以使用者為本，日常決策者的需要才是考量核心。當一切資訊與流程結構，無不以使用者為中心，那麼員工便會深公司誠心幫助他們提高工作效率，而創造出簡單化公司的企業文化。但要如何做呢？本書認為公司要創造讓員工容易了解、感覺比較容易、容易使用、容易執行、容易達成目標的企業環境。 容易了解是讓公司以使用者為中心規劃員工所需的工具、流程、與資訊，以讓員工發揮更大的潛能。感覺比較容易則是建立員工與公司的相互信賴關係，不要把焦點放在科技、數據等事物上。本書提到信賴的起點就是高階主管的承諾，保證為員工準備使用者為中心的工具、資訊、體驗。 容易使用則是員工使用目的為焦點，提供幫助他們整理更簡潔資訊的工具，以避免他們迷失在繁複的細節中。容易執行則是建立利於對話的環境，推動良性辯論，讓正反意見都能充分表達聲音。容易達成目標則是規劃友善的使用環境，容易獲得所需，以提高達成目標的機率。 感想 這本書顯然是站在高階管理者的角度來思考，如何讓員工在簡單的企業環境中更有效率地把事情做好。同人不是高階主管，但這本書讓我在工作的簡單之道上有很大的啟發。 印象中書中一句話深得我心：複雜是無法控制的，你只能建立好成員的關係，讓資訊與溝通通暢無礙，系統會自然演化。同人實際的工作很能體會這一點；任何強調控制與命令，而忽略關係與專業的工作環境，最後只會因為造成管理的困難而失敗。 這本書還沒看完之時，與某位同事討論工作內容，我發現討論主題一再發散而無法聚焦，當時體會到「這個討論怎麼會那麼複雜」，而這種溝通模式卻是技術人員常用的互動模式；談論過多的細節卻未碰觸到問題的重點。可見改善溝通方式會讓我們獲得簡單之道的報酬而讓時間的運用更有效率。 在看完這本書沒多久，剛好聽到朋友提到主管要求他支援某項專案的要求。我知道有些人會認為在台灣的軟體開發生態，對這樣的要求覺得習以為常，但以簡單之道的觀點來看，那位主管以談高調的方式，無法有效地與朋友具體溝通工作內容，同時無法或刻意迴避給朋友必須的工具與支援，讓我可以預見朋友將會陷入複雜的泥淖之中，而浪費青春。 朋友的主管要她加入以 c# 語言開發的專案為例。由於她只會 vb.net，擔心這兩種程式語言有很大的差異，希望主管能夠提供更多協助的承諾。但她的主管卻認為這不成問題，因為同樣是 WinForms，不會有太大的差異。主管表示只要按照 sa 及 sd 開的規格開發就好了，而且到時候發生問題他也不會坐視不管。 [...]]]></description>
			<content:encoded><![CDATA[<p>世界愈複雜，我們就更需要簡單。簡單讓我們看清楚事物的脈絡，掌握重點，以協助做出選擇，並在適當時機採取行動。然而，簡單其實是困難的，因為要做到簡單，意味著我們必須清楚事物的全貎，行動必須要更有原則。尤其是在複雜多變的環境當中，簡單不能只靠直覺，而是有紀律的思考與行動。</p>
<p><a href="http://www.anobii.com/books/越簡單越有力量/9789866739149/019cb0fce2190d24ab/" title="More about 越簡單越有力量"><img src="http://image.anobii.com/anobi/image_book.php?type=3&#038;item_id=019cb0fce2190d24ab&#038;time=1202541764" align=right title="More about 越簡單越有力量" alt="More about 越簡單越有力量" style="padding: 5px;" /></a>那麼，用有紀律的思考與行動，以做到簡單，我們該怎麼做呢？前一陣子，同人閱讀了《<a href="http://www.anobii.com/books/越簡單越有力量/9789866739149/019cb0fce2190d24ab/" title="More about 越簡單越有力量">越簡單越有力量</a>》，我覺得這本書的觀念與方法，剛好可以提供我們複雜世界簡單之道的思考方向與指引。</p>
<p>這本書是作者將自己的公司投入「尋求簡單之道」（search for a simple way）專案的研究心得。這個專案是一項由北伊利諾大學共同贊助的五年計劃，目標是為了研究美國企業資訊時代的規劃與設計工作。研究結果發現企業在改善工作環境、符合客戶與股東期望方面，已有長足顯著的進步；至於如何讓工作各項選擇透明化，進而提供必要的工具與資訊，以提供員工績效，卻相形見絀。</p>
<p>這樣的結果讓我們體會簡單之道的重要性，但什麼是簡單之道呢？本書作者認為簡單就是一種資訊革命，是為了化複雜而明確，也就是製造正確的指令。這些指令照樣鼔勵全面改變、實驗、概念融合、發明、學習；而其背後的大原則，是要為執行工作者釐清問題與真義。</p>
<h4>複雜面向的四個主要來源</h4>
<p>那麼，為什麼我們的工作總是那麼複雜？本書提到根據「尋求簡單之道」的研究結果顯示，造成複雜面向有四個主要來源，依重要性往下排列依序為：</p>
<ol>
<li>
<p>沉重的資訊負荷：有八成的員工與六成的主管找不到、或無法轉化必要資訊，以做出決定。</p>
</li>
<li>
<p>沒效率的溝通：每個人都認為他們盡力去努力溝通，但大部分溝通都缺乏原則。</p>
</li>
<li>
<p>目標宗旨不明：眾多目標欠缺目標整合，整合目標不可缺少領導者的配合。此外，嚴謹的目標設定遮蔽真正授權，掩飾公司內部的缺乏互信。</p>
</li>
<li>
<p>變革欠缺整合：高層主管與員工對整合觀點的懸殊態度，對於整合，領導者關心的焦點是管理、控制與協調的工具；而員工關切的重點是有利個人決策的工具，執行工作者的觀點常會受到不平等的對待。</p>
</li>
</ol>
<p>因此，我們應該如何發揮簡單的力量，減少我們工作的複雜性呢？本書提出簡單必須掌握兩個必要前提，首先必須改變對時間的運用方式，讓我們用更有效率的方式來運用時間。其次管理者應當逆向思考，以使用者為中心，也就是依員工的需要來規劃工具、流程與資訊。此外，簡單之所以有效，是因為兼顧人性與常識兩大原則。本書提到任何以企業邏輯主導變革的失敗，是因為違反了簡單的這兩項原則，以致於沒辦法扭轉人們的行為與習慣而功虧一簣。</p>
<h4>掌控時間</h4>
<p>身為知識工作者，我們該如何更有效率地運用時間呢？書中提到要提高工作效率，必須通過「了解」、「感覺」、「運用」、「執行」、以及「達成任務」這五項基石。針對每一項建立明確性，將強化你對時間的分配運用。</p>
<p>五項基石如何建立明確性呢？我們必須「了解」那些事真正重要，每一個人都必須弄清楚，什麼能帶來最大效益？因為我們可能還沒考慮周詳，就開始要求別人開始著手。我們也必須考慮並準備這項過程能帶來的「感覺」，沒有人做決定絲毫不帶感情。因為考慮怎麼辦的過程，必然有情緒在裡面。「運用」則是我們必須專注在需要派上用場的工具及資源，這是大家完成工作的方法。因為即使大家目標相同，但許多員工卻缺乏必要的工具或訓練。</p>
<p>「執行」是我們必須建立並控制期望，充分了解程序及後續步驟，是最起碼的條件。因為當命令與控制遭到排斥，許多經理人便喪失了澄清目標的能力。所以要讓每一份子知道，誰該在什麼時候擔負什麼責任。「達成任務」則是我們必須對我們想達成的目標，建立可以傳遞的觀點，對於成功的定義，員工與公司看法不同，如果把行為列入考慮，就比較能體會成功的結果。因為人們往往焦頭爛額同時進行多個案子，卻不曉得成功之後又將如何。</p>
<h4>規劃</h4>
<p>本書提到不論計劃規模的大小，規劃者的角色就是為了塑造成功的對話。換句話說，規劃我們必須整合計劃中的每一個小節，讓討論充分發揮效益，以確保眾人的時間、精力都沒有被浪費。如何做呢？書中運用五項基石發展出兩項工具：</p>
<ol>
<li>
<p>了解，感覺，執行：每個人藉以經過討論，弄清楚自己的角色與行為。</p>
</li>
<li>
<p>運用以達成任務：進一步完成工作。</p>
</li>
</ol>
<p>這兩項工具，目的是幫我們整理思緒。它們並不是用來做表面文章，而是提供支援，改變我們支配時間的方式；讓我們把想法或計劃為輕重有序，條理分明的對談。</p>
<h4>行為溝通模式</h4>
<p>本書提到在研究當中，觀察人們在採取行動之前，需要怎樣的資訊。結果研究發現決定採取任何行動的背後，必然隱含下列五個問題：</p>
<p><strong>這和我的工作有何關係？</strong>每個人要關切、要注意的事情太多了，如果我們把注意力擺在所有可能有關的事情上，那將一事無成。如果我們能把我們所說的事情，與大家目前利用時間、精力的方式做個聯繫，那就真的值得一提。</p>
<p><strong>我究竟應該採取哪些步驟？</strong>這不是命令與控制，而是讓期望透明。我們必須充分傳遞下列問題的答案：緊接著的下一步該做什麼？整個流程包括那些環節？誰該負責這個步驟？如果責任轉移，會採取什麼方式告知？</p>
<p><strong>我的表現將如何評估？</strong>結果如何？除了讓員工明確了解自己工作的成效、成功的定義、多久可以得到主管評語等討論之外，還必須了解任務成敗所導致的結果。</p>
<p><strong>有什麼工具與支援可供使用？</strong>大多數的人不是缺乏必要的輔助工具，就是不懂得如何利用。如果能夠連接工作目標和可用的工具，不管我們要做什麼，力量將十分可觀。</p>
<p><strong>對我及我們而言，有什麼意義？</strong>正式的鎬賞或獎勵不見得是唯一的選擇，其它如減輕壓力、提高樂趣、加強團隊精神、以及有更多時間與家人相處也是可以激勵員工的辦法。</p>
<p>如果我們都能致力回答這五個問題，那麼任何談話都會不費吹灰之力，迅速落實為行動；你將馬上獲得眾人的支持與理解，於是會發現要改變時間運用的方式，其實並不困難。</p>
<p>行為溝通模式還能幫我們聆聽與過濾訊息，刪除不必要的資訊以擷取菁華。依據以上五個問題，任何談話、會議、電子郵件都應明確過濾掉未提及「與我做的事有關」、「後續步驟明細表」、「期望」、「能力」、「回報」的資訊。</p>
<h4>以故事來彙整融合</h4>
<p>改變對時間的運用方式，我們需要架構嚴謹的思考與溝通，意味著在採取行動之前，必須好好地思考，用來整理與釐清一切問題。然而，如果我們要釐清問題的對象，是在工作團隊以外的廣大對象，這時就很難用五項基石的概念與他們溝通。本書認為此時必須運用說故事的手法將五項基石融入一個引人入勝的大綱。</p>
<p>所有的故事都包括了衝突、轉變、高潮、結尾四個階段。應對到企業的故事則是企業改革前提開始，意味著員工必須對現行方式有所不滿，才會有動機想採用另一種模式。接著表揚成就，檢討失敗，企業的轉捩點就是當企業慶賀成功、檢討教訓時；在這個時刻，讓員工了解目標達成多少，該如何改進。</p>
<p>企業故事的高潮，是企業今年度成功目標達成之時，把故事架構放在策略方案上，有助讓人們窺見其它架構無法呈現的漏洞。最後由使命、願景、價值觀來結尾，讓員工知道為何而忙，不過必須注意不要只顧談高調而忽略提供必要工具、流程與支援，讓員工能順利發揮潛能。</p>
<h4>以使用者為中心</h4>
<p>本書認為簡單化的公司是以使用者為本，日常決策者的需要才是考量核心。當一切資訊與流程結構，無不以使用者為中心，那麼員工便會深公司誠心幫助他們提高工作效率，而創造出簡單化公司的企業文化。但要如何做呢？本書認為公司要創造讓員工容易了解、感覺比較容易、容易使用、容易執行、容易達成目標的企業環境。</p>
<p>容易了解是讓公司以使用者為中心規劃員工所需的工具、流程、與資訊，以讓員工發揮更大的潛能。感覺比較容易則是建立員工與公司的相互信賴關係，不要把焦點放在科技、數據等事物上。本書提到信賴的起點就是高階主管的承諾，保證為員工準備使用者為中心的工具、資訊、體驗。</p>
<p>容易使用則是員工使用目的為焦點，提供幫助他們整理更簡潔資訊的工具，以避免他們迷失在繁複的細節中。容易執行則是建立利於對話的環境，推動良性辯論，讓正反意見都能充分表達聲音。容易達成目標則是規劃友善的使用環境，容易獲得所需，以提高達成目標的機率。</p>
<h4>感想</h4>
<p>這本書顯然是站在高階管理者的角度來思考，如何讓員工在簡單的企業環境中更有效率地把事情做好。同人不是高階主管，但這本書讓我在工作的簡單之道上有很大的啟發。</p>
<p>印象中書中一句話深得我心：複雜是無法控制的，你只能建立好成員的關係，讓資訊與溝通通暢無礙，系統會自然演化。同人實際的工作很能體會這一點；任何強調控制與命令，而忽略關係與專業的工作環境，最後只會因為造成管理的困難而失敗。</p>
<p>這本書還沒看完之時，與某位同事討論工作內容，我發現討論主題一再發散而無法聚焦，當時體會到「這個討論怎麼會那麼複雜」，而這種溝通模式卻是技術人員常用的互動模式；談論過多的細節卻未碰觸到問題的重點。可見改善溝通方式會讓我們獲得簡單之道的報酬而讓時間的運用更有效率。</p>
<p>在看完這本書沒多久，剛好聽到<a href="http://www.lifeparty.idv.tw/blog/archives/929">朋友提到主管要求他支援某項專案的要求</a>。我知道有些人會認為在台灣的軟體開發生態，對這樣的要求覺得習以為常，但以簡單之道的觀點來看，那位主管以談高調的方式，無法有效地與朋友具體溝通工作內容，同時無法或刻意迴避給朋友必須的工具與支援，讓我可以預見朋友將會陷入複雜的泥淖之中，而浪費青春。</p>
<p>朋友的主管要她加入以 <a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)">c#</a> 語言開發的專案為例。由於她只會 vb.net，擔心這兩種程式語言有很大的差異，希望主管能夠提供更多協助的承諾。但她的主管卻認為這不成問題，因為同樣是 <a href="http://en.wikipedia.org/wiki/WinForms">WinForms</a>，不會有太大的差異。主管表示只要按照 sa 及 sd 開的規格開發就好了，而且到時候發生問題他也不會坐視不管。</p>
<p>朋友並不是不相信 vb.net 和 c# 差別不大，而是希望主管能提供更多學習時間與其它資源或支援的承諾。因為照主管之前的說法，只提供朋友 sample code 讓她參考，而沒有提供額外的指導。主管的「沒有問題」卻難給予具體的保證及方向。</p>
<p>從組織文化的觀察，朋友很難相信那位主管的保證，而且更擔心從專案的問題變成朋友自己的問題。新技術的學習並不是問題，無法充分溝通才是問題複雜面向的主因。</p>
<p>這代表朋友想要明確釐清問題的想法將會被忽視，再加上可以預期專案的不確定性、目標宗旨的不明（主管說按照書面規格開發程式就好，但如果是規格錯誤也要按照錯誤規格來開發，這可能嗎？）等因素，朋友的這項任務的複雜程度，怕只會雪上加霜。看在旁觀者的眼中，也只能把它當成學習簡單之道的負面案例。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/982"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/982/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>當聽到不精確的溝通用詞時</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/929</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/929#comments</comments>
		<pubDate>Fri, 10 Jul 2009 10:14:54 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=929</guid>
		<description><![CDATA[朋友的分享讓同人看到，她的主管用一些不大精確的語言來讓她感覺問題不大。比如說用「c++、vb 都只是工具而已，不管你用那一種工具來開發系統，其實都不會有太大的差異，所以我們大可不用擔心」的說法，正是用不精確的語言來表達不當的概念，這其實是相當要不得的簡化。]]></description>
			<content:encoded><![CDATA[<p>朋友在 <a href="http://en.wikipedia.org/wiki/MSN">MSN</a> 上問我用 <a href="http://en.wikipedia.org/wiki/Visual_Basic_.NET">vb.net</a> 和 <a href="http://en.wikipedia.org/wiki/C%2B%2B">c++</a> 開發程式有沒有很大的不同，因為她的主管要她加入一個使用 <a href="http://en.wikipedia.org/wiki/Visual_C%2B%2B">vc++</a> 開發系統的專案。她很怕接下這個任務會很難上手，但主管告訴他用不同的程式語言，只是工具的差異而已，她只需要依主管給的程式範例照著做就沒有問題。朋友不大相信主管的說法，於是想聽聽我的意見。</p>
<p>同人直覺感到不妥，並非因為朋友並不諳 <a href="http://en.wikipedia.org/wiki/C_language">c</a>/c++ 這種程式語言，加上它與 vb 之間，存在根本的程式語言差異。我認為比較嚴重的問題還是溝通過程出現不精確的語言，這代表她們公司的品質文化，對解決專案的問題是沒有效果的。</p>
<p>學習 c++ 當然並不輕鬆，尤其如果沒有 c 語言基礎的話，學起來更是會格外吃力。因為 c++ 語言特性與 vb 的差異很大。比如 c/c++ 特有的指標，就很容易讓初學者混淆，如果觀念不清楚，常會讓程式產生記憶體衝突甚至是當在不明所以的地方。但程式語言或是程式設計的技術，這些都還可以藉由學習成長，對於積極進取、追求自我成長的開發者而言，這些並非是大問題。</p>
<p>誠如我在 facebook 的好友，也是以前在點空間聚會有一面之緣的仁傑兄，看到我對這件事情的分享，他建議：</p>
<blockquote><p>If you want to encourage her, you can said that. Let her have a confidence to do it.But you have to keep coaching, monitoring and reviewing her codes.
</p></blockquote>
<p>然而，這件事情我覺得讓人擔心的並不是朋友的能力夠不夠。我注意到的是她們公司的品質文化，品質文化的問題並不在技術，它多半不會是專案成敗的關鍵，而是專案管理者的態度。</p>
<p>朋友的分享讓同人看到，她的主管用一些不大精確的語言來讓她感覺問題不大。比如說用「c++、vb 都只是工具而已，不管你用那一種工具來開發系統，其實都不會有太大的差異，所以我們大可不用擔心」的說法，正是用不精確的語言來表達不當的概念，這其實是相當要不得的簡化。</p>
<p><a href="http://www.anobii.com/books/溫伯格的軟體管理學/9789867889720/01c7ec64f7e4bf0927/" title="More about 溫伯格的軟體管理學"><img src="http://image.anobii.com/anobi/image_book.php?type=3&#038;item_id=01c7ec64f7e4bf0927&#038;time=1217763761" align=right title="More about 溫伯格的軟體管理學" alt="More about 溫伯格的軟體管理學" style="padding: 5px;" /></a><a href="http://en.wikipedia.org/wiki/Gerald_Weinberg">溫伯格</a>認為一個軟體開發組織的「品質文化」，重點在於管理者面對品質的態度。他在《<a href="http://www.anobii.com/books/溫伯格的軟體管理學/9789867889720/01c7ec64f7e4bf0927/" title="More about 溫伯格的軟體管理學">第一級評量</a>》提到對軟體工程師而言，沒有什麼觀察技巧比準確聆聽更重要的。為什麼需要準確聆聽？溫伯格指出軟體是一個講求準確的行業。當不準確潛入軟體之中，失敗和危機也就不遠了。但我們如何聽出朋友主管溝通用詞不精確？溫伯格在書中提到不當的概念會使人做出錯誤推論：</p>
<blockquote><p>概念會讓人難以應付的原因是，這樣的概括性觀念通常可提供一個便捷的捷徑。所有的科學和工程領域都是以概念為基礎，這些概念是從觀察少數的案例後為多數未經觀察的案例做出總結。但是，概念會讓我們落入過度簡化的陷阱。</p></blockquote>
<p>如果我們聽到刻意或無意地將概念的使用範圍擴大，那我們就要小心了。好比說朋友主管說「只是」工具，「不管」用那一種工具，「都」不會有問題。如此擴大言語的普遍性，是否朋友的主管想要隱藏什麼資訊呢？實在是值得我們更進一步地深入了解。</p>
<p>事實上，不同程式語言間存在的差異，這些技術細節常會使問題變得複雜，使我們必須花更多的時間來釐清問題。也就是表面上技術似乎是不成問題，但實際上出現的問題，卻會花費許多時間及心力來溝通清楚。尤其是 c++ 和 vb 使用上有很大的差異；程式語言的改變，並不是只要把它們看做是工具的改變那麼簡單。</p>
<p>果然朋友告訴我，她們公司很多 <a href="http://en.wikipedia.org/wiki/Systems_analysis">SA</a> 及 <a href="http://en.wikipedia.org/wiki/System_design">SD</a> 都只會開規格，不管程式是否做得到。後來發生問題卻多半找不到原來的設計者，而結果最後都要重新設計。這讓同人一點都不意外，因為從朋友主管把棘手任務視為燙手山芋；只要有人接就不用管朋友能不能勝任，那不是他的問題而是朋友自己的問題來看。這些都是朋友所任職公司的軟體品質文化使然，而最根本的原因是基於管理者無效的管理行為所造就的呀。</p>
<p><strong>延伸閱讀</strong>：參考<a href="http://www.plurk.com/p/17wqvr">噗浪討論串</a>。</p>
<br /><div class="googlePlusOneButton"><g:plusone href="http://www.lifeparty.idv.tw/blog/archives/929"  size="standard"   ></g:plusone></div><br />]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/929/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

