程式碼高𠅙

2007/08/01

管理寓言:男人愛當顧問

在彭懷真所著的《時間好經營》中,讀到這樣一個管理寓言:

甲君養了隻愛叫春的公貓,每晚嚎叫吵得鄰人無法入睡。在群情激憤下,甲君不得已將公貓送去獸醫處使其不能貓道。幾天過後鄰人仍見那公貓夜夜外出 “辦事”。鄰人不解而問之,甲君便說:牠現在到處去給別人當顧問。

自從聽到這個比喻之後,我就對顧問這個身份感到過敏 (偏偏我的 title 便是顧問)。從上面的故事來看,似乎在諷刺顧問是只剩一張嘴,不能幹正事的人。不過,我在大陸的網站上看到另一個版本,而有不同的解釋:

社區裏,有只公貓,花心,夜夜出去,找母貓鬼混。 後招各家公貓投訴,女主人一狠心,把這只花心貓喀嚓了。 花心貓被喀嚓了後,仍然夜夜出去,回來後竟然更得意。女主人大奇。 花心貓得意地說:“您把我喀嚓之後,我是不行啦,那些公貓也安靜了幾天,不過他們現在都高價請我去做consultant。”

該站作者解說如下:

  • 各家公貓投訴,說明這只貓很有魅力和能力。暗喻在公司裏面能力非常強的sales,但是這個sales很自狂,未處理好同事之間的利益關係,遭同事到老闆那裏投訴。
  • 女主人把這只貓喀嚓了。暗喻老闆是昏君,賢能招妒無善終。
  • 公貓後來被大家聘consultant.暗喻公貓的實戰能力還是大家公認的,做consultant是無奈之舉。

不過我覺得這樣的解釋也有些牽強。有實力的人,何以只能無奈的做consultant。真正有實力的話,不但能在旁指導,甚且可以自己入場打場好球。有道是心寬天地寬,何必自嘲受昏君閹割啊!

2007/07/26

台北市圖書館的貼心服務

大家都知道圖書館可以借書,但若談到預約借書的功能,可能就比較少人知道或使用了。而把預約借書功能發揮到極致的,我想台北市立圖書館算是其中的佼佼者。 預約書籍很簡單,首先,你要辦妥借書證。然後登入台北市立圖書館網站 (密 碼預設是你的生日),搜尋感興趣的書籍。找到書籍後,便可按下畫面上的預約連結進行預約。也許有些書籍只在其他館藏中才找的到,沒關係,台北市圖書館讓你 可以跨館預借,並讓你自由指定所要取書的分館。大概一段時間後 (約一個禮拜),圖書館會幫你把書備妥,送到指定的分館,並發出 email 跟電話通知你在三天內取書--完全不收分文。email 格式長相像下面這樣:
MR. XXX 臺端所預約之以下圖書已到館,請至圖書館辦理借閱, 收到本館通知逾3日未取則(送回原典藏館)上架供其他讀者 閱, 謝謝 ! 請注意︰此郵件是系統自動傳送,請勿直接回覆此郵件,若 需要請直接與(取書館)聯絡。 1 XXXXX/ AAAA ; BBB, CCC譯 AAAA call number:000.0 0000 copy:1 2 YYYY: YYYYYYY/ DDDD. EEEEE著 ; FFF譯 DDDD call number:111.1 1111 copy:1
如果你想,甚至可以要求圖書館將書透過貨運送到你家,而你只要出資支付貨運費即可。 Anyway,這是一項相當體貼便民的服務。不過我也擔心,若是使用這服務的人多了起來,是不是會造成圖書館的作業成本太高…考慮到這點,還是把借回來的書努力的 K 完再說吧。 ※ 2007/9/1 另一點通知:台北市圖書館用悠遊卡也可以借書了喔! 詳情見此

2007/01/25

雜牌軍現象與石油提鍊作用

問題很簡單,就是團隊裡面誰會出線,支援前線作戰!而其後果又會對組織造成何種影響?

站在支援部門這邊的觀點,若是支援前線這檔子事對於本身無利可圖,那麼她所派出的傭兵將可能是團隊內貢獻能力最少的成員。每個被要求支援的部門都把 "功能較弱" 的成員交給外部專案經理,最後,整個專案團隊的組成就成了雜牌軍。此謂雜牌軍現象!

與此極端相反的狀況稱為石油提鍊作用:支援外部專案的人員必須經過外部公司的專案經理審核,審核不過者只能留在組織內進行內部專案… 這個程序,有如石油提煉的過程:

– 天然煤氣分餾溫度在20°C以下
– 汽油分餾溫度在20~150°C
– 輕油分餾溫度在120~220°C
– 柴油分餾溫度在200~360°C
– 重油分餾溫度高於360°C
– 最後的殘餘物—瀝青

不同外部專案的經理把最好的人才,次好的人才,再次好的人才一層層的過濾出去,最後留在組織內的就只剩瀝青了。這對公司內部專案的進行,甚至是公司的核心進化產生莫大的阻礙。

不管是雜牌軍現象還是石油提鍊作用,都在彰顯一個準則:組織要能建全運作,必需能留住優秀人力。

人力的組成決定打法,更決定勝負。

這就像玩牌一樣,手中握有的牌,永遠會主宰你發牌的順序。若是手中僅有幾張王牌時更要小心,太早發了,後面就後繼無力,遭人宰制。晚點發,就可能永遠也發不出去。最好是想辦法換牌,調整手中部位。我相信,有些組成是不用下場玩,就知道勝負如何了。

如何成為令人倚重的程式設計師之另類思考

昨晚與好久不見的朋友餐敘,提及當年某公司有一個 "優秀" 的 RD 部門主管及另一個 "重要" 的程式設計師。那位 "優秀" 的 RD 部門主管總會用正規的方式設計,有良好的軟體架構,並且開發過程中及完成後,都會提供其設計文件、使用手冊或範例程式。
另外有一個公司所 "倚重" 的程式設計師--並不是說他不優秀,只是他對公司的重要性,大於他的優秀性。
公司裡面複雜的系統,只有他能維護。而前人所留下的程式,並沒有相關的文件說明該系統的整體架構設計跟思維。
這就產生了一個有趣的現象:對於一個程式設計師而言,把事情做到最好 (除了寫程式外,還寫了讓人看得懂的文件等等),對他本身而言並不一定是好事。當別人越了解你的系統,你的可替代性就越高,那麼你的價值不就越低?
反之,若有人能寫出他自己才看得懂的程式碼,就算上級要求寫文件,也是寫一些高深莫測、形而上學的東西(諸如,用90%的篇幅介紹物件導向的基本觀念,然後說明只要了解物件導向或設計模式的觀念,再自行 trace 程式,就能理解系統運作)。
這樣一來,後人無法維護該套系統,完全是後人資質不佳或能力不足。這樣,他就成為令人倚重的程式設計師了。
以上所言,並不代表本人立場!
PS: 即使是某公司那一位令人倚重的程式設計師,也沒有達成我上述的要求,因為他沒有寫出需要睿智才看得懂的文件。何況,那些不可維護的程式碼,他也曾經力圖改良,想讓人看懂過!

2007/01/02

我的一點 Thunderbird 使用訣竅

自從進入目前公司後,我便一直以 Thunderbird 作為我的 email client,算算時間也三年半以上。這一路走來,我發展了許多 Tunderbird 的應用密技,我想有許多可能是別人沒想過要這樣用的,特別發表出來,與各位分享。

(一) 利用 Message Filter, 將所有不在 Personal Address Book 中的來信,全部移到 Junk 信件夾


因為垃圾信實在太多,只好使出這招釜底抽薪的方式。如果是業務、專案上的初次來信,通常事先會透過電話連絡。此時只要手動自 Junk 中移回 Inbox,再將寄件人加入 Address Book,下次即不會再跑到 Junk box 中。

(二) 快速安裝 extension 的方式


在 https://addons.mozilla.org/thunderbird/ 裡面找到所要安裝的 extensions 後, 在網頁的 Install Now 按鈕上選右鍵,選 "複製連結網址"。然後打開 Thunderbird  的 Add-ons 管理員,按 Install,在 Select an extension to install 檔案對話窗中,在檔名文字欄位按 Ctrl+V 貼上 extension URL,再按下開啟,就會進行安裝程序。

(三) 用 7-zip 來修改 extension 的安裝資訊

如果你也是嚐鮮一族,已在使用 Thunderbird 2.0,那麼你將遭遇最大的問題極可能是 extension 版本的不支援。如果你願意碰碰運氣,可採用下面這種作法:

1. 以 7-zip 開啟 extension 的 xpi 或 jar 檔案
2. 在壓縮檔案的 install.rdf 按右鍵選編輯
3. 7-zip 會以你設定的編輯器開啟 install.rdf,找到類似以下這一段,將其中的 em:maxVersion 元素值調整到你的 Thunderbird 版本以上,例如 2.*,然後存檔,關閉編輯器

       
           
                {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
                1.0
                1.5.*
           

       


4. 7-zip 將提示你檔案已被修改過,是否要更新壓縮檔之訊息,請選擇確定,然後重新安裝 extension 即可。

(四) 用 Plaxo 同步通訊錄

不曉得你有沒有因為重灌電腦而遺失通訊錄的經驗呢?重灌電腦時,我通常會記得備份信件,但是聯絡人卻老是因忘了備份通訊錄而流失。

Plaxo 是一個線上服務,提供通訊錄、行程、作業及記事管理等諸多功能。對於 Thunderbird 而言,最實用的地方在於它提供通訊錄同步的 extension。我把 Plaxo 當成是我的通訊錄管理員,因為它支援了匯整、備份、同步聯絡人的功能:

  • 匯整:我把 MSN、Yahoo!、GMail 上所有的連絡人全數匯入 Plaxo 中
  • 備份:經上述匯整後,Plaxo 成為我唯一一個需要維護通訊錄的地方。因為在資料存在 Server 上,只在 Plaxo 還在,我永遠不怕通訊錄再次流失
  • 同步:因為使用多台電腦,而且我在不同的地方都裝有 Thunderbird,我可以透過 Plaxo 同步不同機器上的連絡人

在 Thunderbird 2.0 上安裝 Plaxo,由於 Plaxo Thunderbird Extension 目前只支援到 Thunderbird 1.5,所以請用前述的方法以 7-zip 來修改 extension 的安裝資訊。另外,個人覺得 Plaxo Toolbar 的設計極醜。若要隱藏 Plaxo Toolbar,可在選單列上選擇 PlaxoPreferences,將 Plaxo Preferences 對話窗中的 Show Toolbar check box 取消即可。

(五) 使用 Duplicate Contacts Manager 移除重複連絡人

當我使用 Plaxo 合併 MSN、Yahoo!、GMail 上的連絡人時,常會造成連絡人重複。透過 Duplicate Contacts Manager 這個 extension,可以快速找出重複聯絡人,並選擇保留與移除的項目。在移除重複連絡人後,從選單列執行 PlaxoSync,你會發現 Plaxo 通訊錄裡面重複的連絡人也被移除了。

(六) 將寄件備份與收件資料夾合併

我將寄件備份放在 Sent 信件夾中,Inbox 用來保留最新的信件。每隔一段時間,我會將 Inbox 裡的信件移到 Sent 信件夾。如此,在 Sent 資料夾中採用 Thread 模式檢視時,我獲得一個類似 GMail 的 Message Thread 介面,可以很方便的看到發信與回信的脈胳。

(七) 將老舊的信件移存到不同的信件夾中

將較老舊的信件,以年為單位封存到不同的信件夾之中,可以避免掉 Thunderbird 同一信件夾不得大於 4G 的限制。

(八) 使用 Remove Duplicate Messages 移除重複信件

有時在不同的信件夾間複製或移動信件後,會造成同一資料夾內信件重複的狀況。使用 Remove Duplicate Messages 這個 extension,可以快速的刪除重複的信件。在信件刪除完畢後,別忘了在該資料夾上執行 Compact,如此才能真正的減少信件檔案的儲存空間。

(九) 善用 To(收件人) 或 Subject 信件表頭欄位分類信件
我知道 Thunderbird 2.0 已正式加入對 Tag 的支援。但是我所採用的方式,不但適用於 Thunderbird 1.x,而且比之 Tag 的操作更為簡易。作法很簡單:在編輯新信時,我會把 To 欄位拿來輸入分類關鍵字,我稱為 To tags。例如,這篇 blog 就是在 Thunderbird 中編寫的。我將此信件的 To 欄位分別加上 blog, note, thunderbird 三行。如果是內收信件,就需要 TB Header Tools Extension 這樣的 extension 才能更改信件表頭。對於內收信件,我通常會透過修改 Subject 的方式,來分類信件,如 [Project:Company].... 這樣的格式。

(十) 善用 Search  Folder  建立分類檢視

Draft 信件夾原本放置外寄信件的草稿,在我為信件加上 To tags 後,它變成個人記事資料夾。我進一步為 Draft 信件夾建立各種查詢條件的 Search  Folder 來設定分類檢視。例如我有個 Search  Folder 名為 "部落記事",其查詢條件為 "to Contains blog";另有個 "生活記事" 則對應為 "to Contains diary"。當然,透過 Search Folder 可建立更複雜的查詢條件。

同樣的,專案的分類檢視也可透過建立 Search Folder 為之,只是查詢條件會變成 "subject Contains Project:Company" 這樣的型式。

(11) 拿 Drafts 信件夾當記事薄

之所以拿 Drafts 信件夾當記事薄,而非別的信件夾的原因是:預設 Thunderbird 所有新信存檔時都會存放在 Drafts 信件夾中。你可以在 Drafts 信件夾重複編輯信件,而不用擔心它會跑到別處。要 Tag 分類的功能,可用上述的 To tags;要樹狀分類的功能,則可用 Subfolder 結合 Search Folder。

當初會想用 Thunderbird 來做記事管理,另一個原因是它的 Rich Editor 功能實在做的太好。而信件又可夾帶附檔,加入圖片。再說,除非你只用 Web Mail,否則電腦裡極可能需要一套 email client,既是如此,那何不就把它的應用效益最大化,這樣又少了需要另外安裝記事軟體的需求。

2006/08/23

Doing Ajax the SCA Way

興趣盎然的閱讀著 tempo 所作的投影片「AJAX 的 client/server 溝通機制探究」,裡面提到了「如果你流落荒島, 但是只能帶一個 AJAX Framework, 建議你帶 DWR」。這句話引起我對 DWR 極大的興趣。
其 實我們公司內部已經採用 Echo2 開發產品 (而且用的很高興)。Echo2 最大的優點是可讓我們完全擺脫 HTML、Javascript 編輯時擾人的細節,完 完全全以乾淨的 Java 程式碼開發出極為動態的 Ajax 應用程式,但相對的它的缺點是會耗費大量的 Session 資源。因此如果想要開發 Community Style 的網站時,就不適合採用 Echo2 了。所以一直以來,我對較為傾向於 stateless, 單純 RPC 導向的 ajax framework 還是保持一定的注意。
看著 DWR 的範例程式碼,讓我有種似曾相識的感覺。我突然回想起,先前在 JavaTwo 中我所介紹的 Tuscany SCA 也有提供 Ajax Remoting 的功能。再回頭去翻翻 Tuscany SCA 所提供的 ajax client 端範例程式碼,嗯!它的風格一樣也是簡潔明瞭。

以 Tuscany 設計 Ajax 的 Server 端服務
直接以 Tuscany 的範例做說明,假設我們在 Server 端有個類別如下:
public interface HelloWorldService {
    public String getGreetings(String name);
}

@Service(HelloWorldService.class)
public class HelloWorldServiceComponentImpl implements HelloWorldService {
    public String getGreetings(String name) {
        return "jsonrpcHello " + name;
    }
}

為了要讓這個類別變成 Client 端 JSON-RPC 可以呼叫的服務,我們在 sca.module 中定義其 entryPoint 及 component wire:



   
       
       
        HelloWorldServiceComponent/HelloWorldService
   


   
       
   

  

在 Client 端使用 Ajax 服務

最後,我們在 client 端就可以使用 Tuscany 所提供的 "SCA 物件",簡單的使用 server 上的服務操作:

:

:

:

:

嗯嗯... 這裡似乎隱約就可嗅到 SCA 所強調的 unified programming model。即使使用 javascript 來呼叫 service,它的用法幾乎與標準的 Java client 沒有多大差異。

在 Ajax client 呼叫 Web Services
另 外,SCA 還有一項特長,就是可以「把別人家的 Web Services 包裝起來變成自家的元件」。這在 Ajax 手法下特別有用,因為受限於 security issues,Ajax 無法由 client 端向不同的網站發出 ajax request。透過 SCA「把別人家的 Web Services 包裝起來變成自家的元件」的特長,我們可以在 sca.module 中集成不同網站的 web services,然後用 entryPoint 匯出成可在 client 端以 JSON-RPC 呼叫的服務。 有興趣的朋友,可以參考 Tuscany 所附的 scahelloworldjsclient 範例。

一點提醒

到這裡,有朋友心動,想用 SCA 來寫 Ajax 了嗎?哎~~ 還是提醒心動的朋友,出了事情要想辦法自己解決,因為網路上很少人談到這樣的作法。而且肯定的,至少在目前為止,在網頁元素的 binding 上,SCA 所提供的支援應該較為單調。至少我還不知道,是否有內建的 function call,只要一個指令,就可以把 service 傳回 string array binding 到 html 的 select 元素上。當然自己寫也不會太難就是了!

一個問題
最後,有一個問題我納悶很久了,很想問問 tempo:既然流落荒島,那為什麼還要帶一本 Ajax 的書呢?那時候我可能會帶「與食人族共舞」或「24 小時學會獨木舟造船術」。嗯…「螃蟹的 24 種吃法」也不錯,如果有的話。

2006/08/22

從 Separation of Concerns 談 AOP 與 SOA

AOP (Aspect-oriented Programming) 強調的是面向分割 (separation of concern),並且試圖由程式語言 (compiler)、框架 (framework) 或執行期 (runtime) 層次對橫切物件功能的服務考量 (crosscutting concerns) 提供支援。

AOP 本身是開發應用程式框架的有力工具,透過 AOP 的手法,可以輕易解決傳統 OOP 窒礙難行的問題。例如充斥在整個系統中的橫切服務--包括日誌、交易、安全的議題,都可透過 AOP 的支援而輕易實作出來。

不過 AOP 也引入一些問題,例如透過 AOP 手法建築的系統,其元件間的互動關係較難以理解及追蹤,因此個人認為 AOP 適用於開發 application framework 的底層,但卻並不適合拿它直接來開發應用系統。

 而個人對於 SOA 所謂的 Concerns 則有二種看法:
  • Business Concerns: 如何達到 (business) services independency
  • 如 同 AOP 中之 crosscutting concern:這在 SOA 中給它負予了一個可怖的稱謂,叫 Enterprise Concerns,其實也不過就是 log, monitor, access rights 這些非使用者功能導向的服務需求。不過 SOA 不在程式語言、編譯器或框架(framework)上解決此議題,而在架構層級解決
SOA 之所以也能達到 separation of concerns 的訴求,完全是因為它將服務的兩端抽象化,並將呼叫訊息化。在 client 與 service 之間,可以加入許多的 proxy, router, interceptor 這樣的東東,因此可以在兩造之間加入許多的 QoS(Quality of Services, 即上述的 Enterprise Concerns)。

這樣一來,這些 QoS 就可獨立出來個別設計,再於佈署時期或執行時期動態的設定,也就達到 separation of concerns 的訴求。從這個面向來說,SOA 達到了最為動態的 AOP。不過,相對的 SOA 之切點的設定便無法如傳統 AOP 的作法 (在程式語言上下功夫) 那樣的精密了。