<?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, 05 Mar 2010 04:18:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>
]]></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>
]]></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>
]]></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 開的規格開發就好了，而且到時候發生問題他也不會坐視不管。
朋友並不是不相信 vb.net 和 c# 差別不大，而是希望主管能提供更多學習時間與其它資源或支援的承諾。因為照主管之前的說法，只提供朋友 sample code 讓她參考，而沒有提供額外的指導。主管的「沒有問題」卻難給予具體的保證及方向。
從組織文化的觀察，朋友很難相信那位主管的保證，而且更擔心從專案的問題變成朋友自己的問題。新技術的學習並不是問題，無法充分溝通才是問題複雜面向的主因。
這代表朋友想要明確釐清問題的想法將會被忽視，再加上可以預期專案的不確定性、目標宗旨的不明（主管說按照書面規格開發程式就好，但如果是規格錯誤也要按照錯誤規格來開發，這可能嗎？）等因素，朋友的這項任務的複雜程度，怕只會雪上加霜。看在旁觀者的眼中，也只能把它當成學習簡單之道的負面案例。
]]></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=4&#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>
]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/982/feed</wfw:commentRss>
		<slash:comments>1</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=4&#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>
]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/929/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>聚餐也談品質流程</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/488</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/488#comments</comments>
		<pubDate>Fri, 08 May 2009 10:31:24 +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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/?p=488</guid>
		<description><![CDATA[在台灣，品質最大的問題是人們習慣將品質流程獨立於設計及開發過程之外，以為兩者是可以完全分割的。然而這種思維對品質的結論就會是「把做好的東西丟到另一端去」，讓開發人員認為品質是品質部門的責任，而品質部門則認為提昇品質不是他們的責任，以為最多只能做到知道產品有問題，而不知道如何改善它們，只能退回到開發人員那邊來解決。 ]]></description>
			<content:encoded><![CDATA[<p>本周一同人在新公司 on board，公司事先訂好餐廳為我舉行迎新聚餐。在這場聚餐當中的一道菜，讓大家開啟談論品質流程的話題。</p>
<p>某同事甲指著一道菜，跟負責點菜的同事乙說：下次就別再點這道菜了。他說那道菜的肉，咬下去裡面是白的，顯見豬肉並沒有先醃過，吃起來就不夠味。這時候，有些同事表示認同，紛紛也附和同事甲的意見來評論這道菜。</p>
<p>同人對同事甲的看法沒有什麼意見，因為說實在的，我也吃不出這道菜有什麼不好。不過，如果精於美食的同事甲說得是正確的，那麼就代表這家店的這道菜品質有問題。於是我說：這其實代表他們 QA 沒做好。</p>
<p>這時候，大家好奇的眼光看著同事丙，也就是公司 QA Leader。他說 QA 沒有辦法提昇產品的品質，它只能確保有問題的產品不會送到客戶的手中。</p>
<p>顯然同事丙和同人對 QA 的定義有顯著的不同，他所說的 QA 是針對產品本身的控制流程，而非針對產出保證產品品質的執行過程，我認為那是 QC 而非 QA。但同人並不想挑戰對方對 QA 的定義，以免把吃飯的氣氛弄得太嚴肅，於是我用另一種方式來表達我的觀點：</p>
<blockquote><p>我的意思是作這道菜的流程出了問題，導致產出無法符合顧客對品質的要求。所以他們應該設法改善這道菜的製作流程，讓它更完整並且可以符合客戶的需求。</p></blockquote>
<p>終於，同事丙沒有再質疑同人的說法。不過，這也讓人看到一個現象，就是在台灣，品質最大的問題是人們習慣將品質流程獨立於設計及開發過程之外，以為兩者是可以完全分割的。然而這種思維對品質的結論就會是「把做好的東西丟到另一端去」，讓開發人員認為品質是品質部門的責任，而品質部門則認為提昇品質不是他們的責任，以為最多只能做到知道產品有問題，而不知道如何改善它們，只能退回到開發人員那邊來解決。 </p>
<p>在一個重視品質文化的公司，QA 人員對產品的意見當然可以擲地有聲，善盡到品質管制的責任。然而，在台灣軟體開發的環境，尤其是大部分以專案型態的軟體開發，品質往往是時間或成本不足第一個被犧牲的對象。同人想到我過去在一個大型政府公共建設委外 BOT 專案中，因為業主對文件要求嚴格，使開發團隊要花費相當多的心力來寫文件。想不到上層負責監督的 VP 卻說：沒有時間，品質目標只要設定為達到 30% 就夠了。</p>
<p>同人很清楚那位 VP 的說法是不會 work 的，因為品質不能妥協，否則你必將付出更大的代價。果然那個因為延誤而讓公司損失慘重的專案，在我離開那個專案兩三年後才勉強結案驗收。不幸地，這種不重視品質文化的開發方式，在今天卻還在台灣各地持續上演之中。</p>
<p>因此，與其將品質寄望在強大的 QA 人員或嚴謹的品質流程，還不如在開發過程中織入品質的面向，形成品質保證的<a href="http://en.wikipedia.org/wiki/Holographic_principle">全像圖</a>。高品質是全員參與的必然結果，在分析、設計過程就加入如何提昇品質的思維，以達到符合顧客的需求，並且創造他們的價值，這便是執行所謂的 QA，也就是真正的品質保證。</p>
<p>當然，能夠為客戶創造價值的品質流程並非絕對的，就像負責點菜的同事乙後來表示，她不覺得那道菜難吃呀。其實同人也覺得那道菜也還好，品質和你的客戶是誰有很大的關係，事實上，並不是每一個人都對吃很講究，所以那道菜的品質，其實是因人而異呀。</p>
<p><strong>後記：</strong></p>
<p>本篇文章已<a href="http://www.zdnet.com.tw/members/1000103060/blog/?v=post&#038;id=10000208">刊登</a>於 ZDNet Taiwan <a href="http://www.zdnet.com.tw/members/1000103060/blog/">部落格文章專區</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/488/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>訊息交易的抽象化思考</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/431</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/431#comments</comments>
		<pubDate>Tue, 03 Feb 2009 10:00:22 +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/archives/431</guid>
		<description><![CDATA[在〈開發者的 common sense〉的留言中，同人看到一些網友的批評。我發現這些批評顯示了有些開發者不擅於抽象化思考，而習慣於用經驗法則來取代思考。然而，誠如 Brooks 所言：「軟體的本質是複雜的，而不是偶然發生的」對治複雜度本來就是開發者的天職，而軟體開發的抽象化思考則是其用以統理複雜度的利器。由此看來，那些網友的批評著實令人為他們捏一把冷汗呀。
從路邊的垃圾桶與路人的留言，我們可以發現他們弄錯 common sense 的意思。他們認為 common sense 不能一概而論，因為每個人的 common sense 都不同。但這樣的觀點令人感到疑惑，如果每個人的 common sense 都不一樣，所以無法一概而論，那這種 common sense 還能叫做 common sense 嗎？
到底他們觀點上邏輯的矛盾，問題是出在那裡呢？同人認為問題並不是開發者的 common sense 不存在，而是忽略了開發者應該將經驗化成一般性的通用概念。舉例來說，軟體工程領域本身就是從實務發展出來的理論，其中許多概念就是開發者必須知道的 common sense，對開發者來說是合理的知識，也是他們都知道、無須解釋或加以論證的常識。
由此可知，如果開發者缺乏一般性的通用概念，那他碰到問題就很難舉一反三，自然也就難以掌握重點，而只能依據表相來處理問題，往往使得問題變得更複雜。oofunp 的留言就很像欠缺概念思考的開發者常見的反應，一開始以自己熟悉的技術來看問題，最後才發現自己對問題的理解是錯誤的。尤其「以為抽象化是將資料庫定義抽象化」的想法，更是整個弄錯抽象化思考的意義，結果最後他還是誤解了業務規則的意思。
同人前一篇文章所提到的業務規則，並非來自技術領域上萬用的設計，而是對問題領域經過抽象化思考後，所萃取而得到可以解決業務需求的重要概念。顯然 oofunp 的誤解是以技術的角度來看待抽象化思考，才會產生嚴重的觀念混淆。事實上，抽象化思考重視的不是技術實作，而是如何從實際問題當中萃取出重要的抽象概念，以增進我們對問題領域的瞭解，才能採用最適當的技術來開發軟體系統。
此外，過份強調技術經驗而輕忽概念性思維的開發者，很容易表現出自己對問題的盲目。就像 X files 留言的批評一樣，責怪同人沒有交待清楚是 XML 格式的問題，直到別人提出質疑才說明與列出參考文獻，認為同人缺乏部落格文章寫作的 common sense。但我的文章已經很清楚地提到是有關「交易訊息」語法的問題，難道他不瞭解交易訊息是 XML 技術的一般化抽象概念表述嗎？XML 只是實現交易訊息概念的一種技術，用以解決跨系統整合的問題。如果他要看到 XML 字眼才知道是訊息格式的問題，那改天換了另一種交易訊息的實作方式，我想大概他腦筋又要轉不過來了吧。
以上網友的三種批評，表面上看起來好像是不同的問題，但其背後都存在同樣的本質，那就是從交易訊息的問題中可見一斑，他們無法以抽象性思考來看待軟體開發的問題。但為什麼開發者需要抽象化思考呢？可能有人會認為，只有 OOA、OOD、或是 OOP 才會需要抽象化思考，不用物件導向的開發典範，應該不需要抽象化思考。其實這樣的觀念是錯誤的，不管我們採用什那一種開發典範來開發系統，抽象化思考都是必備的能力，只是不同的開發典範需要不同的抽象層面。
 抽象思考本來就是人類本能的思維能力，讓我們可以因應變化掌握事物的核心關鍵。這正是《易經繫辭》所言「一陰一陽之謂道，繼之者善也，成之者性也。仁者見之謂之仁，知者見之謂之知，百姓日用而不知。故君子之道鮮矣」的道理，我們常在不知不覺中運用抽象化的概念。最近看到《世紀末軟體革命復刻版》說得好，從小我們就具備了抽象的思考能力，我們可以把我們所關心的特性，從事物中「抽」出來，看出一些形而上、感官之外、富於意義的特性來。
這本書還提到有關抽象化思考的一個重點，事物的意義是針對問題的需要而來。世間事物的特性多到數不清，但藉由抽象化的過程，我們可以把它抽象化為只剩下一些我們需要的特性。我們只要掌握這些關心的特性，就可以讓世間的事物更容易處理。例如一般人所知道的「冰」，在愛斯基摩人眼中卻可分類為十幾種，只因為需要不一樣；我們只要知道冰的概念就行了，但愛斯基摩人對於冰的用處有許多，所以需要更細膩冰的分類。因此，因應需要的不一樣，抽象化思考的結果也會有所不同。
讓我們回到訊息交易系統的開發，抽象化思考通常被稱做資訊隱藏，萃取最有意義的資訊，並去除其它不必要的資訊。以欄位內容取值為例，空白或是空值都只是眾多可能參考欄位內含值的一種，不論空白與否，都不影響系統實際運作的處理程序，因此空白或空值與否的資訊，對系統並不重要應予以略除，這是屬於語法層次的抽象化思考。
當然在實際業務的需要上，空白或空值可能會有特殊的意義，但那並非欄位取值過程本身應該處理的問題，而是由取值後續的檢核資料合理性的規則來處理，這是屬於語意層次的抽象性思考。雖然為了系統執行效能的考量，語法與語意可能會寫在同一支程式或程序當中。但以程式的設計概念來看，因為技術實作的因素混淆語意與語法，而破壞設計概念的整體性，則是無異於自廢武功而使軟體品質問題層出不窮。
相信沒有人會否認良好的設計概念應該是「分而治之」，我們在某些訊息交易的標準中，也確實看得到語法與語意分而治之的例子。例如一些 EDI 的訊息標準會以 MIG（訊息建置指引）來規範交易訊息格式，包括欄位的強制性、可重覆出現的次數、欄位可能的內含值來代表訊息的語法，而且多半是通行於相同功能領域的共通語法。而對於相同功能領域不同的交易，則會以 SIG（系統建置指引）來規範特定交易的訊息語意，用來關聯到實務上的業務規則。
早年的 EDI 訊息交易的系統，很多都不是用物件導向的方法所實作出來的，但其系統結構卻與物件導向的抽象化思維不謀而合，這代表什麼呢？同人還是喜歡引用《易經繫辭》的道理，正是「天下事一致而百慮，殊途而同歸」、「易窮則變、變則通、通則久」，事物的核心本質本來就存在，只在於我們如何找出有意義的概念出來，並且加以演化而讓系統不斷進展，重點還在於我們懂不懂得抽象化思考呀。
]]></description>
			<content:encoded><![CDATA[<p>在〈<a href="http://www.lifeparty.idv.tw/blog/archives/430">開發者的 common sense</a>〉的留言中，同人看到一些網友的批評。我發現這些批評顯示了有些開發者不擅於<a href="http://en.wikipedia.org/wiki/Abstraction">抽象化思考</a>，而習慣於用經驗法則來取代思考。然而，誠如 <a href="http://en.wikiquote.org/wiki/Fred_Brooks">Brooks</a> 所言：「軟體的本質是複雜的，而不是偶然發生的」對治複雜度本來就是開發者的天職，而軟體開發的抽象化思考則是其用以統理複雜度的利器。由此看來，那些網友的批評著實令人為他們捏一把冷汗呀。</p>
<p>從路邊的垃圾桶與路人的留言，我們可以發現他們弄錯 common sense 的意思。他們認為 common sense 不能一概而論，因為每個人的 common sense 都不同。但這樣的觀點令人感到疑惑，如果每個人的 common sense 都不一樣，所以無法一概而論，那這種 common sense 還能叫做 common sense 嗎？</p>
<p>到底他們觀點上邏輯的矛盾，問題是出在那裡呢？同人認為問題並不是開發者的 common sense 不存在，而是忽略了開發者應該將經驗化成一般性的通用概念。舉例來說，軟體工程領域本身就是從實務發展出來的理論，其中許多概念就是開發者必須知道的 common sense，對開發者來說是合理的知識，也是他們都知道、無須解釋或加以論證的<a href="http://zh.wikipedia.org/w/index.php?title=常識&amp;variant=zh-tw">常識</a>。</p>
<p>由此可知，如果開發者缺乏一般性的通用概念，那他碰到問題就很難舉一反三，自然也就難以掌握重點，而只能依據表相來處理問題，往往使得問題變得更複雜。oofunp 的留言就很像欠缺概念思考的開發者常見的反應，一開始以自己熟悉的技術來看問題，最後才發現自己對問題的理解是錯誤的。尤其「以為抽象化是將資料庫定義抽象化」的想法，更是整個弄錯抽象化思考的意義，結果最後他還是誤解了業務規則的意思。</p>
<p>同人前一篇文章所提到的業務規則，並非來自技術領域上萬用的設計，而是對問題領域經過抽象化思考後，所萃取而得到可以解決業務需求的重要概念。顯然 oofunp 的誤解是以技術的角度來看待抽象化思考，才會產生嚴重的觀念混淆。事實上，抽象化思考重視的不是技術實作，而是如何從實際問題當中萃取出重要的抽象概念，以增進我們對問題領域的瞭解，才能採用最適當的技術來開發軟體系統。</p>
<p>此外，過份強調技術經驗而輕忽概念性思維的開發者，很容易表現出自己對問題的盲目。就像 X files 留言的批評一樣，責怪同人沒有交待清楚是 XML 格式的問題，直到別人提出質疑才說明與列出參考文獻，認為同人缺乏部落格文章寫作的 common sense。但我的文章已經很清楚地提到是有關「交易訊息」語法的問題，難道他不瞭解交易訊息是 XML 技術的一般化抽象概念表述嗎？XML 只是實現交易訊息概念的一種技術，用以解決跨系統整合的問題。如果他要看到 XML 字眼才知道是訊息格式的問題，那改天換了另一種交易訊息的實作方式，我想大概他腦筋又要轉不過來了吧。</p>
<p>以上網友的三種批評，表面上看起來好像是不同的問題，但其背後都存在同樣的本質，那就是從交易訊息的問題中可見一斑，他們無法以抽象性思考來看待軟體開發的問題。但為什麼開發者需要抽象化思考呢？可能有人會認為，只有 <a href="http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design">OOA、OOD</a>、或是 <a href="http://en.wikipedia.org/wiki/Object_Oriented">OOP</a> 才會需要抽象化思考，不用物件導向的開發典範，應該不需要抽象化思考。其實這樣的觀念是錯誤的，不管我們採用什那一種開發典範來開發系統，抽象化思考都是必備的能力，只是不同的開發典範需要不同的抽象層面。</p>
<p><a href="http://www.anobii.com/books/002b0bcc4b2bca5604/" title="更多關於世紀末軟體革命復刻版"><img src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=002b0bcc4b2bca5604&amp;time=0" style="padding: 5px; display: inline; float: right" title="更多關於世紀末軟體革命復刻版" alt="世紀末軟體革命復刻版的圖像" width="93" height="132" /></a> 抽象思考本來就是人類本能的思維能力，讓我們可以因應變化掌握事物的核心關鍵。這正是《易經繫辭》所言「一陰一陽之謂道，繼之者善也，成之者性也。仁者見之謂之仁，知者見之謂之知，百姓日用而不知。故君子之道鮮矣」的道理，我們常在不知不覺中運用抽象化的概念。最近看到《<a href="http://www.anobii.com/books/002b0bcc4b2bca5604/" title="更多關於世紀末軟體革命復刻版">世紀末軟體革命復刻版</a>》說得好，從小我們就具備了抽象的思考能力，我們可以把我們所關心的特性，從事物中「抽」出來，看出一些形而上、感官之外、富於意義的特性來。</p>
<p>這本書還提到有關抽象化思考的一個重點，事物的意義是針對問題的需要而來。世間事物的特性多到數不清，但藉由抽象化的過程，我們可以把它抽象化為只剩下一些我們需要的特性。我們只要掌握這些關心的特性，就可以讓世間的事物更容易處理。例如一般人所知道的「冰」，在愛斯基摩人眼中卻可分類為十幾種，只因為需要不一樣；我們只要知道冰的概念就行了，但愛斯基摩人對於冰的用處有許多，所以需要更細膩冰的分類。因此，因應需要的不一樣，抽象化思考的結果也會有所不同。</p>
<p>讓我們回到訊息交易系統的開發，抽象化思考通常被稱做<a href="http://en.wikipedia.org/wiki/Information_hiding">資訊隱藏</a>，萃取最有意義的資訊，並去除其它不必要的資訊。以欄位內容取值為例，空白或是空值都只是眾多可能參考欄位內含值的一種，不論空白與否，都不影響系統實際運作的處理程序，因此空白或空值與否的資訊，對系統並不重要應予以略除，這是屬於語法層次的抽象化思考。</p>
<p>當然在實際業務的需要上，空白或空值可能會有特殊的意義，但那並非欄位取值過程本身應該處理的問題，而是由取值後續的檢核資料合理性的規則來處理，這是屬於語意層次的抽象性思考。雖然為了系統執行效能的考量，語法與語意可能會寫在同一支程式或程序當中。但以程式的設計概念來看，因為技術實作的因素混淆語意與語法，而破壞設計概念的整體性，則是<a href="http://www.lifeparty.idv.tw/blog/archives/262">無異於自廢武功而使軟體品質問題層出不窮</a>。</p>
<p>相信沒有人會否認良好的設計概念應該是「分而治之」，我們在某些訊息交易的標準中，也確實看得到語法與語意分而治之的例子。例如一些 <a href="http://en.wikipedia.org/wiki/Electronic_Data_Interchange">EDI</a> 的訊息標準會以 MIG（訊息建置指引）來規範交易訊息格式，包括欄位的強制性、可重覆出現的次數、欄位可能的內含值來代表訊息的語法，而且多半是通行於相同功能領域的共通語法。而對於相同功能領域不同的交易，則會以 SIG（系統建置指引）來規範特定交易的訊息語意，用來關聯到實務上的業務規則。</p>
<p>早年的 EDI 訊息交易的系統，很多都不是用物件導向的方法所實作出來的，但其系統結構卻與物件導向的抽象化思維不謀而合，這代表什麼呢？同人還是喜歡引用《易經繫辭》的道理，正是「天下事一致而百慮，殊途而同歸」、「易窮則變、變則通、通則久」，事物的核心本質本來就存在，只在於我們如何找出有意義的概念出來，並且加以演化而讓系統不斷進展，重點還在於我們懂不懂得抽象化思考呀。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/431/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>一句話改變我對高捷的評價</title>
		<link>http://www.lifeparty.idv.tw/blog/archives/420</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/420#comments</comments>
		<pubDate>Mon, 05 Jan 2009 04:13: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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/420</guid>
		<description><![CDATA[元旦假期到高雄遊玩，我們搭乘高鐵到高雄，然後以高捷做為連結各個景點的主要交通工具，最後再搭乘台鐵回台北。藉著這次機會，讓同人有了第一次體驗乘坐高捷的經驗，本來對服務人員的悉心解說、與親切的服務態度，讓我對高捷有很好的印象。但可惜在最後，搭高捷到火車站卻因為服務人員的一句話，改變了我對高捷系統的服務評價。
由於先前擔擱了一些時間，使我們到達火車站的時間顯得有點趕，而就在這緊要關頭，在捷運出口閘門前，捷運車票竟然出現問題。連續試了幾次，並且換了不同的閘門再試，結果都是一樣，於是同人只好求助於捷運站的服務人員。
看到服務人員忙於處理買票，覺得她的動作很慢、加上老婆在閘門外催促，我們快要趕不及搭火車的時間了。於是同人向服務人員表示，我們趕著搭火車，但捷運票卻無法投入到出口閘門中。
沒想到服務人員卻丟了一句「要排隊」讓同人覺得很生氣，但為了趕時間不想與對方吵架，於是只得隱忍不發。最後，才能讓她慢吞吞地帶我走出閘門，好在還有時間讓我們趕上火車。
這位服務人員的服務態度，改變我對高捷系統的服務評價，從原先的親切及熱誠轉變為官僚與冷漠。同人認為這種服務水準，站在客戶的立場來看，根本就沒有品質可言，令人懷疑高捷對服務人員的訓練可能有問題。
以資訊倫理的觀點來看，系統在運作時出現問題，到底是誰的責任？答案顯而易見，再怎麼樣也不會是客戶的責任。簡單的閘門入出口操作，同人又不是第一次使用，因此不可能是操作或使用不當的問題，而是高捷系統的穩定性不佳。
因此，「要排隊」這句話只是服務人員自己忙不過來，卻怪罪到客戶身上，責怪他們不排隊用來減輕自己的工作壓力。但忽視自己應該立即排除系統瑕疵對客戶所造成的障礙，而要求客戶花費自己的時間來解決問題，只會讓客戶感受到服務人員冷漠的官僚心態、以及其缺乏解決問題的專業能力。顯然這位服務人員的心態出現了問題，應該需要再教育才能提供夠水準的服務品質。
從事系統開發多年，同人當然非常清楚系統在運作過程中，出現問題是在所難免，讓面對客戶的服務人員相當辛苦。但身為服務人員，如果沒有將心比心思考客戶的問題，表現出熱忱的服務態度。對客戶而言，服務人員的辛勞只是用來塘塞服務品質不良的理由或藉口罷了。
]]></description>
			<content:encoded><![CDATA[<p>元旦假期到高雄遊玩，我們搭乘高鐵到高雄，然後以高捷做為連結各個景點的主要交通工具，最後再搭乘台鐵回台北。藉著這次機會，讓同人有了第一次體驗乘坐高捷的經驗，本來對服務人員的悉心解說、與親切的服務態度，讓我對高捷有很好的印象。但可惜在最後，搭高捷到火車站卻因為服務人員的一句話，改變了我對高捷系統的服務評價。</p>
<p>由於先前擔擱了一些時間，使我們到達火車站的時間顯得有點趕，而就在這緊要關頭，在捷運出口閘門前，捷運車票竟然出現問題。連續試了幾次，並且換了不同的閘門再試，結果都是一樣，於是同人只好求助於捷運站的服務人員。</p>
<p>看到服務人員忙於處理買票，覺得她的動作很慢、加上老婆在閘門外催促，我們快要趕不及搭火車的時間了。於是同人向服務人員表示，我們趕著搭火車，但捷運票卻無法投入到出口閘門中。</p>
<p>沒想到服務人員卻丟了一句「要排隊」讓同人覺得很生氣，但為了趕時間不想與對方吵架，於是只得隱忍不發。最後，才能讓她慢吞吞地帶我走出閘門，好在還有時間讓我們趕上火車。</p>
<p>這位服務人員的服務態度，改變我對高捷系統的服務評價，從原先的親切及熱誠轉變為官僚與冷漠。同人認為這種服務水準，站在客戶的立場來看，根本就沒有品質可言，令人懷疑高捷對服務人員的訓練可能有問題。</p>
<p>以資訊倫理的觀點來看，系統在運作時出現問題，到底是誰的責任？答案顯而易見，再怎麼樣也不會是客戶的責任。簡單的閘門入出口操作，同人又不是第一次使用，因此不可能是操作或使用不當的問題，而是高捷系統的穩定性不佳。</p>
<p>因此，「要排隊」這句話只是服務人員自己忙不過來，卻怪罪到客戶身上，責怪他們不排隊用來減輕自己的工作壓力。但忽視自己應該立即排除系統瑕疵對客戶所造成的障礙，而要求客戶花費自己的時間來解決問題，只會讓客戶感受到服務人員冷漠的官僚心態、以及其缺乏解決問題的專業能力。顯然這位服務人員的心態出現了問題，應該需要再教育才能提供夠水準的服務品質。</p>
<p>從事系統開發多年，同人當然非常清楚系統在運作過程中，出現問題是在所難免，讓面對客戶的服務人員相當辛苦。但身為服務人員，如果沒有將心比心思考客戶的問題，表現出熱忱的服務態度。對客戶而言，服務人員的辛勞只是用來塘塞服務品質不良的理由或藉口罷了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/420/feed</wfw:commentRss>
		<slash:comments>8</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>
]]></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/368</link>
		<comments>http://www.lifeparty.idv.tw/blog/archives/368#comments</comments>
		<pubDate>Wed, 13 Aug 2008 04:52: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>

		<guid isPermaLink="false">http://www.lifeparty.idv.tw/blog/archives/368</guid>
		<description><![CDATA[新政府團隊似乎想要在就職典禮的活動上，改變舊制以發揮新創意，營造出耳目一新的感覺。但實際上卻反而把問題複雜化，造成一團混亂。這讓筆者想到在軟體開發過程中，也經常出現同樣的情況。改革的困難正是考驗著領導者的領導能力，他應該如何領導團隊來進行成功的改革呢？]]></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,20130746,00.htm">新官上任三把火</a>〉與〈<a href="http://www.zdnet.com.tw/enterprise/column/softwaredev/0,2000087962,20131046,00.htm">新官上任三把火(下): 建立團隊的創新文化</a>〉兩篇文章刊出。原稿未經 ZDNet 編輯，其內容可能會與刊登的文章內容有約略的不同。</p>
<p>新政府能否為台灣開創新局還有待觀察。但從馬蕭辦公室與府院籌辦五二○就職典禮，卻出現許多的問題，加上當天的慶典南北奔波，被稱為有史來最複雜的就職典禮看來；新政府團隊似乎想要在就職典禮的活動上，改變舊制以發揮新創意，營造出耳目一新的感覺。但實際上卻反而把問題複雜化，造成一團混亂。這讓筆者想到在軟體開發過程中，也經常出現同樣的情況。</p>
<p>許多主導專案改變的領導者總是新官上任三把火，認為專案應該要進行改變以展現出自己的決心與魄力，因此要求團隊改變開發流程。然而，專案時間與資源的限制多半很難讓團隊有足夠的時間來調適或熟悉改變後的開發流程，結果總是令專案團隊倍感艱辛。</p>
<p><strong>改革的困難正是考驗著領導者的領導能力</strong>，他更需要懂得如何讓團隊發揮創意與執行力來實現改革的目標。領導者應該如何領導團隊來進行成功的改革呢？筆者認為從領導者的價值觀、流程方法的改變、以及團隊的創新文化這三方面來看，我們可以從中體會到專案成功改變的箇中三昧，以助於<u>掌握改革重點，有效地組織資源來幫助團隊實現改革目標</u>。</p>
<h4>領導者的價值觀</h4>
<p>多數的開發者都希望能夠盡其所能地追求完美，然而，受限於許多因素，他們必須有所取捨。例如，專案時程及資源的限制總是讓他們不可能採用最佳的開發流程來發展解決方案，往往只能針對解決特定問題來選用最適當的開發流程。</p>
<p>因此，主導改變的領導者必須要了解沒有最完美的開發流程，而只有適用於解決某些問題的開發流程。這是領導者必須建立的價值觀，才能確保專案在正確的方向進行改革。</p>
<p><a href="http://www.anobii.com/books/013ad41f7a862e80dd/" title="更多關於溫伯格的軟體管理學"><img src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=013ad41f7a862e80dd&amp;time=0" title="更多關於溫伯格的軟體管理學" alt="溫伯格的軟體管理學的圖像" style="padding: 5px" align="right" border="0" /></a>然而，許多領導者希望專案改變開發流程，並不是基於專案的實際需要，而是基於個人在情感上的需要，希望團隊能用更成熟的方式來開發系統。知名的軟體顧問溫伯格卻提醒我們，追求不必要的完美並不是成熟，而是幼稚。他在《溫伯格的軟體管理學：系統化思考（第1卷）》中表示：</p>
<blockquote><p>正如我們所親眼看到的，文化的模式無所謂較成熟或不成熟，而只有合適或不合適。當然啦，有些人對於追求完美有其情感上的需要，而他們會將此情感上的需要加諸在他們所做的每一件事上。他們會做這樣的比較，完全與機構所面臨的問題無關，而只與他們自己的問題有關。</p></blockquote>
<p>溫伯格提到在軟體工程界有許多所謂的改革者，其改革工作的第一步是要求他們要改革的「對象」先承認自己從前是低劣的，結果這些改革者皆未能遂行其願。他認為如果我們的目標是為了改變一個機構，一開始就不應該用有比較優劣意味的用語，例如「成熟」這類偏頗的字眼。<sup>[1]</sup></p>
<p>筆者發現，確實有些人會用「成熟」與否來對流程模式進行價值比較。例如，當年神通在高鐵售票系統出現紕漏時，在網路上筆者曾看到有人認為 CMMI 要達到 ML4 才算品質達到改善的水準，而 ML3 也只是了解流程的情況而已，因此算不上是品質有達到改善。筆者認為<a href="http://www.lifeparty.idv.tw/blog/archives/58">這樣的說法是有問題的</a>。</p>
<p>其實任何流程模式所產出的品質應該都是相同的，它們都必須能夠解決組織與專案的問題、以及符合客戶的要求。因此，<strong>如果主導改革者的心態不是基於解決的問題或客戶的要求，而是基於自己情感的訴求，所謂的改革也只不過為了遂行其願的私心，卻讓專案與團隊成為無辜的陪葬品</strong>。這都是因為領導者沒有建立起正確的價值觀。</p>
<h4>流程方法的改變</h4>
<p>在軟體產業中，或許是受到用工程來隱喻開發過程的影響，許多人都希望能夠發展出<a href="http://www.lifeparty.idv.tw/blog/archives/220">放諸四海皆準的開發方法</a>，以增進開發的效率及降低溝通成本。如果可以用標準化的方式來主導開發流程的變革，進而讓團隊落實良好的開發制度，似乎就意味著可以增進開發的效率並確保品質，但事實上真的是如此嗎？</p>
<p><a href="http://www.anobii.com/books/01dc7d45cbe3e8fadc/" title="更多關於Peopleware"><img src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=01dc7d45cbe3e8fadc&amp;time=0" title="更多關於Peopleware" alt="Peopleware的圖像" style="padding: 5px" align="right" border="0" /></a>《Peopleware：腦力密集產業的人才管理之道》提到基層的流程改善乃是知識工作者的基本作為，但是，正式的流程改善卻是把責任從個人向上轉移至組織。個人還有可能會勤訓苦練，並且提昇良好的技能，但組織就只會把東西制度化，而危機就在制度化當中。</p>
<p>制度化會讓組織不願意去冒險，也不會尋求真正的挑戰。而且當工作流程獲得了實質改善，工作就會愈艱難。因為把比較瑣碎的工作交由機器去做，或把不重要的事情從專案中剔除之後，剩下的沒有被替除的工作將會變得更知識密集，需要更多技術與經驗。也就需要更有天份，更有經驗的人來做事。</p>
<p>另外，經過改善的方法，讓人們可以從事更艱難的挑戰。如果我們不敢面對這些挑戰，我們就會採取穩紮穩打的行為以規避風險，但如此一來，這些專案也只能帶來低利潤。<sup>[2]</sup></p>
<p>由此可知，<strong>流程方法的改變其實並不意味著可以提昇專案的績效。如果團隊的能力不足，再有效率的流程方法也只能讓團隊只能勝任簡單而低利潤的專案</strong>。而依照筆者的觀察，愈依賴組織開發制度的團隊，其創新能力愈難以發揮。因為團隊成員的想法多半會受到制式的標準或規範所限制，難以對解決問題產生新的創見。因此，要讓團隊的創意得以發揮，應該重視成員對問題的見解，而不是用組織的制度來僵化他們的思考。</p>
<h4>團隊的創新文化</h4>
<p>不管開發方法多麼創新，達成專案目標的最後關鍵終究還是在於執行層面，否則最後必然發生如「誰來幫貓掛鈴鐺」的困窘局面。筆者的一個朋友曾經分享過他對共通性開發方法的看法：</p>
<blockquote><p> 方法論都是要讓問題簡化以適用大部分的情況；可是就如同郭台銘說過的一句話：「魔鬼就藏在細節中」。</p></blockquote>
<p><a href="http://www.anobii.com/books/0009244ebdbfe0a08a/" title="更多關於專案管理之美學"><img src="http://image.anobii.com/anobi/image_book.php?type=4&amp;item_id=0009244ebdbfe0a08a&amp;time=0" title="更多關於專案管理之美學" alt="專案管理之美學的圖像" style="padding: 5px" align="right" border="0" /></a>因此，與其相信存在終極流程可以保證解決所有問題，還不如發揮團隊的效能，讓成員們可以在細節中展現他們的專業與創意。如同《專案管理之美學》這本書所提到的，不要把焦點擺在流程及方法上，專案經理應該把焦點放在團隊上，規劃和追踪系統必須符合專案的複雜度，以及團隊的文化。</p>
<p>這本書提醒我們，每個團隊和專案都不同，對過去的判斷有所質疑，通常都有很好的理由。因此如果只是因為有本書或某位執行長說要做某事，或者上個月或去年採用了某項技術，並不表示今天也適用。<sup>[3]</sup></p>
<p>筆者常看到許多具有優秀人才的團隊，常常無法發揮整體效能，其主要的原因多半是團隊缺乏創新的文化。尤其位於組織高階的管理者或自視甚高的顧問經常以為他們所主導的流程有必然成功的原因，無法容忍別人有不一樣的意見，於是破壞了<a href="http://www.lifeparty.idv.tw/blog/archives/63">團隊的創新文化與創意思考</a>。</p>
<p>其實，軟體開發是知識與腦力密集的行業，有效地溝通比流程與規範的遵循還來得重要。換句話說，<strong>如果我們沒有因應專案的複雜度與團隊文化來調適與熟悉開發方法，堅持按照開發方法照章行事很容易讓我們對專案問題產生迷惘</strong>。這正是新官上任三把火最大的問題呀。</p>
附註：
&nbsp;<hr/><ol class="footnotes"><li id="footnote_0_368" class="footnote">曾昭屏譯（2006），《溫伯格的軟體管理學：系統化思考（第1卷）》，經濟新潮社。</li><li id="footnote_1_368" class="footnote">方亞瀾、錢一一譯（2007），《Peopleware： 腦力密集產業的人才管理之道》，經濟新潮社。</li><li id="footnote_2_368" class="footnote">陳建勳、劉漢山譯（2006），《專案管理之美學》，歐萊禮。</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.lifeparty.idv.tw/blog/archives/368/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
