我的雲端生活網 - Life+
Tuesday, May 19, 2009
imoo msn機器人即將支援 傳遞客製化表情符號
imoo msn機器人傳遞客製化msn表情符號測試是成功了,不過;真的要做進產品,也許;還需要考慮其他的部份 比如:怎麼做可以方便機器人的發送… 畢竟測試的版本要進產品還需要一些時間,但這星期確定會釋出這個功能
Thursday, May 14, 2009
在企業組織裡設計的挑戰
本文翻譯 Contextual Design 一書 (Amazon 記錄) 第 10 頁到第 16 頁 (Google Books 預覽): The Challenge For Design in Organizations 。
在書中,「設計」一詞幾乎都是指「開發資訊系統」。
標色文字是我的註解。
在企業組織裡設計的挑戰
誰能說一套系統將能做什麼?真是行銷部門或系統分析師說:「搞出這個」,就能教開發團隊只跟隨規格做事嗎?或者,行銷人員或分析師真的只要說:「弄出『這一類的』東西」,開發團隊其實決定做他們想要做的以及決定系統該是哪個樣子?事實上,兩方人馬都要擔任說明新系統是什麼長相的角色──在企業組織裡,建立一套系統是他們這些人合作的結果?
下層的問題無可逃避。今日的系統太大,很難教一個人做完。所以企業組織把規定和建立系統的流程分為幾個部份,把每個部份指派給一小群人。每群人又特定他們負責的部份,與其他處理其餘部份的人失去聯係。在開發系統的事情上,有四個問題該答,這些問題傾向於將開發流程自然分割。所以很容易指定一群人回答一個問題。問題有這些:「工作中有哪些事項」──該認定工作的哪幾個方面;「該如何應對」──團隊該用什麼系統做應對;「系統該如何架構」──到底有什麼功能、功能的規劃、以及系統架構,能適合工作的需要;以及「我們做得怎麼樣」──所設計的系統真的能為客戶服務嗎?
(「工作中有哪些事項」──該認定工作的哪幾個方面 )
頭一個問題 (「有哪些?」) 是問,有哪些客戶的工作活動是新系統該認定的,有哪些提議或問題該克服、有哪些角色和工作項目有必要支援。指定回答這個問題的那群人是行銷人員或商務分析人員。在管理工作會改變企業組織的時候,他們常下指令定義企業資訊系統有哪些是要項。他們說:「採購的費用太多了。給每個部門一張信用卡,只有授權才准使用」、或說「咱們的化學資料庫是咱們的命脈。把所有資料庫跟公司綁在一起。」或者,行銷部們可能會告誡工程團隊說:「設計一項產品支援公司的計劃。」或「讓產品放到網路上。」這些指令說了好多高層次的工作方面的事項,要系統能夠幫忙,卻沒有實際定義系統。把產品放到網路上,影響工作的哪方面呢?把資料庫都綁在一起,意思是一個資料庫呢、重複的資料庫呢、還是一種搜索許多資料庫的方法?在那些設定方向的觀點上,上述問題則是細節,他們不必回答這些小問題。
(「該如何應對」──團隊該用什麼系統做應對 )
回答這些小問題,意味要說要應付些什麼:公司將要如何回應這些有關系統設計、流程、服務、以及發行策略的議題。行銷人員可能是定義回應方式的參與者,但除了公司都是技術導向之外。需求分析人員可能也是參與者,但除了這些人真的太不懂技術了,就要是開發人員來做了之外。客戶自己應該要涉入內部系統,因為系統定義了他們要怎麼工作。行銷人員和分析人員可能要得到正式許可「發展系統規格」,但是依照經驗,他們不在必須寫程式的層面中定義系統的行為。「他們丟了一份規格給我,」開發人員都這樣對我們說。接著,「但是老是有太多我們要決定的事情,而他們通常只問我們那些不夠實際的事情。所以這個叫做交換意見。」
(「系統該如何架構」──到底有什麼功能、功能的規劃、以及系統架構,能適合工作的需要 )
決定要怎麼架構系統,意味要具體決定要納入什麼功能,具體上系統怎麼動,還有系統會怎麼顯現視窗、選單或畫面。這幾乎都是開發人員做的事,也表示他們要了解使用系統的工作環境。要不然他們不能做什麼對客戶好的決定。開發團隊無法從行銷人員或分析師手中拿到客戶資料。做出詳細的系統架構仰賴於額外一層的客戶資料,開發人員要自己拿到──或者是,自己做出感覺對的系統。有些公司又走得很遠,把開發團隊擺在與他們客戶和分析師有差別的地位,創造了一群專精在他們設計工作中的人力。但那只是弄得需要更多溝通,而且如果缺少車馬費,就造成更嚴重的孤立。
(「我們做得怎麼樣」──所設計的系統真的能為客戶服務嗎 )
最後一個設計的問題,說,「我們做得怎麼樣?」這個問題是和客戶核對系統的進度,確認它還是個對的系統,而且在細節層次改動程式不會讓系統變得不能用。這個問題經常分割出去給一組可用度研究團隊或品質保障團隊做測試。回答這個問題,是檢查系統本身 (看看 bug 和是否符合規格) 以及跟使用者一起測試系統。但無論哪方面,處理檢查結果都是開發者的工作。所以,他們必須接收回報訊息,還要了解它並相信它──那表示他們要買進取得回報訊息的程序,並且信任收集回報訊息的人。並且經常是,到目前為止都沒有真的取得實際資料做設計,在這個時候發現的缺陷都是很基本,他們在開發階段很難確實找到的。
這些定義系統該如何的不同部份,若系統設計程序要啟動,就要一起做。界定應對方案的人要能答覆真實的問題;建立系統的人要建構他們認同的應對方案。但是,要保持每個問題都分別由指定的人來處理,會造就組織之間的溝通難題。開發的正式文件掌握擬定的設計方案,也要盡力控制各群人馬之間的溝通和歧見。「你們簽了協議。表示你們承諾了。」「是,不過我們已經了解並且真的不需要。」或「是的,但是我們與這位重要客戶談過,若我們沒有碰上需要,就沒有必要出貨。」或「是,但是依現有的技術我們真的沒能力實作。」
組織裡的設計,與在各群人之間發展同一凝聚的方向有關:符合他們打算交付的公司應對方式。並不是永不改變,而是在改變時,整個企業組織在各種功能上可以適當地回應,而不是將改變轉換為兩方人馬的叫囂。反過來說,同一凝聚的願景仰賴於在公司應對方向的發展之間多加考慮不同的觀點。行銷和分析人員需要科技方面的展望,看見新系統種類的契機。開發人員需要行銷觀點來看清為什麼有些走向造就好產品,有些卻不能。又需要分析師的看法,看到他們要處理的工作要點。資訊科技團隊需要客戶的看法,確定自己提議的工作流程變更很合理而且可採用。在他們發展出公司的應對方式之後,他們可以同時有效地做事,並且不會迷失方向。但是,在突出的設計上,跨功能團隊做得最好。
實際環境中的工作團隊
建立跨功能團隊來做一同的設計會執行出真實企業組織裡某些意外的問題。想想一個基本問題:這樣的團隊要符合什麼期待?快速檢視大部份組織的實際結構,就發現他們都做到讓人們分開。最常見的開發工作環境是小方塊,是一塊夠大的一人空間,可以舒服地做事,有電腦和桌子。但是那個區域沒有大到可以讓幾個人一起舒服地工作,也沒有一塊大的隔牆空間讓一支團隊工作。當然另外有會議室,但會議室的特色就是只能預約並共用幾個小時。因為預約時間有限,能提供的工作只是短時間完成的事情,不超過半天。以超過標準的方式預約這個房間,同事的樣子會讓你擺臭臉。畢竟是在浪費一塊公用空間。不但如此,因為房間是共用的,你不能擺太多東西。每次對談要從頭開始,每次會議要重新攤開設計圖。
所以會議室支援的工作是在能短時間做好,而不需要實體支援的類型──不要硬體、不要圖表,沒有你不能捲起來帶著走的東西。也許有網路線,但要接上哪個區域網路呢?網路品質還不錯吧?接上筆記型電腦怎麼樣呢?有這些限制,會不會有開發人員和工程師覺得開會浪費時間呢?有標準規模的公司的實體架構明白地說,真正的工程都在小方塊裡做成的,而人都來到會議室則是他們沒有真在做事。企業的普通結構,沒有可以支援面對面溝通而能啟動系統設計的。
管理面對面的設計
一同有效地工作,意思是擁有在其中能真正工作的場所,讓許多人面對面地完成工作。也意味了賦與人們人際能力和流程,使他們的聚集比較有效。有一位部門主管指出一件棘手的問題,是在當地旅店訂房間讓五位資深架構師待著,並告訴他們,如果不在一週內提出解決方案,就要辭退他們。他得到結果,而我們發現如果人們有合理的工作過程,通常會比較快樂、有創造力,並且更快產生結果。對程序的典型回應是「感謝你,我現在終於知道該做什麼。」即使痛恨程序的人也會這麼說。
一起工作是一種新技能。是學校沒教的事,也是工作很少教的事。一起有效地工作,意味要懂得怎麼時常維持設計方面的對話,要怎麼用心到工作要項而不是其他事情上,要怎麼掌控每個人的特質,還有要怎麼發現並指出歧見的根本原因。如果團隊不這樣做,他們的工作就會因為人們處理歧見的模式與保持他們愉快的工作凝聚力之間的取決,而遭受損失。
人們處理歧見的一種主要的模式是政治交易:「我覺得你弄錯了。但是,如果你給我一些對我來說比較重要的東西,我就容得了你。」政治交易帶出一套以拼湊為主的系統,缺少具備向心力的主題。而且政治交易讓團隊的每個人都減少對設計工作投注心力,因為每一位都至少要認同一個人的決定,而他認為那個決定是錯的。
也有其他處理歧見的方法,但是大都不夠好。有一種方法是妥協,說:「你說我們要把什麼都做成對話方塊,但我覺得應該要做成按鈕才對。所以,兩種都做,我們誰都高興了。」誰都高興了,不過使用者不高興。他們有一打達到功能的辦法,但是沒有好的理由說明哪個辦法比較好。或者,會有教師式的歧見處理方式,說:「大師最聰明,而且什麼都懂。我們要跟著做大師所說的。」這很好,但除了在科技環境、圖形使用者介面設計、使用者實際工作、行銷、專案規劃、以及其他能力方面,這些絕對不錯的大師們所佔的人口數少到幾乎沒有。
情境設計 (Contextual Design) 規定一種發展系統的過程,可以帶出人際技能的價值。規定了根據資料來取捨各種開發選項,所參考的資料不包括爭議和政治交易。情境設計規定了人該扮演的角色,能在設計的過程中一直保持討論。不但要讓設計的過程比較有效率,還要因為人們爭議並沒有進展而將系統暫時擱到一邊。
前端系統設計讓我們著眼於人際的課題,因為設計程序的這一部份會帶來由面對面影響得很深的不一樣的功能。傳統的設計較不帶出著重在一起工作的技能。致力於保持客戶工作的凝聚力,而排除團隊中不同的看法和不同的能力,會使認知到如何一起工作變得很重要。我們發現,在人們該進行明確的流程、扮演明確的角色時,那時他們會對個人風格很敏感,使他們在房間裡起衝突。而當他們有具體的資料可以根據以設定決策,就會跨過隔籬,一起有效地工作。
這就是以客戶為中心的意義:不只做到客戶導向的設計,還要讓設計流程將系統帶往能讓客戶的工作──從開始到實作──能凝聚在系統中。對情境設計的挑戰是內建在方法中,要瞭解一同工作的要點,還要提供有效工作的辦法。
在書中,「設計」一詞幾乎都是指「開發資訊系統」。
標色文字是我的註解。
在企業組織裡設計的挑戰
誰能說一套系統將能做什麼?真是行銷部門或系統分析師說:「搞出這個」,就能教開發團隊只跟隨規格做事嗎?或者,行銷人員或分析師真的只要說:「弄出『這一類的』東西」,開發團隊其實決定做他們想要做的以及決定系統該是哪個樣子?事實上,兩方人馬都要擔任說明新系統是什麼長相的角色──在企業組織裡,建立一套系統是他們這些人合作的結果?
下層的問題無可逃避。今日的系統太大,很難教一個人做完。所以企業組織把規定和建立系統的流程分為幾個部份,把每個部份指派給一小群人。每群人又特定他們負責的部份,與其他處理其餘部份的人失去聯係。在開發系統的事情上,有四個問題該答,這些問題傾向於將開發流程自然分割。所以很容易指定一群人回答一個問題。問題有這些:「工作中有哪些事項」──該認定工作的哪幾個方面;「該如何應對」──團隊該用什麼系統做應對;「系統該如何架構」──到底有什麼功能、功能的規劃、以及系統架構,能適合工作的需要;以及「我們做得怎麼樣」──所設計的系統真的能為客戶服務嗎?
(「工作中有哪些事項」──該認定工作的哪幾個方面 )
頭一個問題 (「有哪些?」) 是問,有哪些客戶的工作活動是新系統該認定的,有哪些提議或問題該克服、有哪些角色和工作項目有必要支援。指定回答這個問題的那群人是行銷人員或商務分析人員。在管理工作會改變企業組織的時候,他們常下指令定義企業資訊系統有哪些是要項。他們說:「採購的費用太多了。給每個部門一張信用卡,只有授權才准使用」、或說「咱們的化學資料庫是咱們的命脈。把所有資料庫跟公司綁在一起。」或者,行銷部們可能會告誡工程團隊說:「設計一項產品支援公司的計劃。」或「讓產品放到網路上。」這些指令說了好多高層次的工作方面的事項,要系統能夠幫忙,卻沒有實際定義系統。把產品放到網路上,影響工作的哪方面呢?把資料庫都綁在一起,意思是一個資料庫呢、重複的資料庫呢、還是一種搜索許多資料庫的方法?在那些設定方向的觀點上,上述問題則是細節,他們不必回答這些小問題。
(「該如何應對」──團隊該用什麼系統做應對 )
回答這些小問題,意味要說要應付些什麼:公司將要如何回應這些有關系統設計、流程、服務、以及發行策略的議題。行銷人員可能是定義回應方式的參與者,但除了公司都是技術導向之外。需求分析人員可能也是參與者,但除了這些人真的太不懂技術了,就要是開發人員來做了之外。客戶自己應該要涉入內部系統,因為系統定義了他們要怎麼工作。行銷人員和分析人員可能要得到正式許可「發展系統規格」,但是依照經驗,他們不在必須寫程式的層面中定義系統的行為。「他們丟了一份規格給我,」開發人員都這樣對我們說。接著,「但是老是有太多我們要決定的事情,而他們通常只問我們那些不夠實際的事情。所以這個叫做交換意見。」
(「系統該如何架構」──到底有什麼功能、功能的規劃、以及系統架構,能適合工作的需要 )
決定要怎麼架構系統,意味要具體決定要納入什麼功能,具體上系統怎麼動,還有系統會怎麼顯現視窗、選單或畫面。這幾乎都是開發人員做的事,也表示他們要了解使用系統的工作環境。要不然他們不能做什麼對客戶好的決定。開發團隊無法從行銷人員或分析師手中拿到客戶資料。做出詳細的系統架構仰賴於額外一層的客戶資料,開發人員要自己拿到──或者是,自己做出感覺對的系統。有些公司又走得很遠,把開發團隊擺在與他們客戶和分析師有差別的地位,創造了一群專精在他們設計工作中的人力。但那只是弄得需要更多溝通,而且如果缺少車馬費,就造成更嚴重的孤立。
(「我們做得怎麼樣」──所設計的系統真的能為客戶服務嗎 )
最後一個設計的問題,說,「我們做得怎麼樣?」這個問題是和客戶核對系統的進度,確認它還是個對的系統,而且在細節層次改動程式不會讓系統變得不能用。這個問題經常分割出去給一組可用度研究團隊或品質保障團隊做測試。回答這個問題,是檢查系統本身 (看看 bug 和是否符合規格) 以及跟使用者一起測試系統。但無論哪方面,處理檢查結果都是開發者的工作。所以,他們必須接收回報訊息,還要了解它並相信它──那表示他們要買進取得回報訊息的程序,並且信任收集回報訊息的人。並且經常是,到目前為止都沒有真的取得實際資料做設計,在這個時候發現的缺陷都是很基本,他們在開發階段很難確實找到的。
這些定義系統該如何的不同部份,若系統設計程序要啟動,就要一起做。界定應對方案的人要能答覆真實的問題;建立系統的人要建構他們認同的應對方案。但是,要保持每個問題都分別由指定的人來處理,會造就組織之間的溝通難題。開發的正式文件掌握擬定的設計方案,也要盡力控制各群人馬之間的溝通和歧見。「你們簽了協議。表示你們承諾了。」「是,不過我們已經了解並且真的不需要。」或「是的,但是我們與這位重要客戶談過,若我們沒有碰上需要,就沒有必要出貨。」或「是,但是依現有的技術我們真的沒能力實作。」
組織裡的設計,與在各群人之間發展同一凝聚的方向有關:符合他們打算交付的公司應對方式。並不是永不改變,而是在改變時,整個企業組織在各種功能上可以適當地回應,而不是將改變轉換為兩方人馬的叫囂。反過來說,同一凝聚的願景仰賴於在公司應對方向的發展之間多加考慮不同的觀點。行銷和分析人員需要科技方面的展望,看見新系統種類的契機。開發人員需要行銷觀點來看清為什麼有些走向造就好產品,有些卻不能。又需要分析師的看法,看到他們要處理的工作要點。資訊科技團隊需要客戶的看法,確定自己提議的工作流程變更很合理而且可採用。在他們發展出公司的應對方式之後,他們可以同時有效地做事,並且不會迷失方向。但是,在突出的設計上,跨功能團隊做得最好。
實際環境中的工作團隊
建立跨功能團隊來做一同的設計會執行出真實企業組織裡某些意外的問題。想想一個基本問題:這樣的團隊要符合什麼期待?快速檢視大部份組織的實際結構,就發現他們都做到讓人們分開。最常見的開發工作環境是小方塊,是一塊夠大的一人空間,可以舒服地做事,有電腦和桌子。但是那個區域沒有大到可以讓幾個人一起舒服地工作,也沒有一塊大的隔牆空間讓一支團隊工作。當然另外有會議室,但會議室的特色就是只能預約並共用幾個小時。因為預約時間有限,能提供的工作只是短時間完成的事情,不超過半天。以超過標準的方式預約這個房間,同事的樣子會讓你擺臭臉。畢竟是在浪費一塊公用空間。不但如此,因為房間是共用的,你不能擺太多東西。每次對談要從頭開始,每次會議要重新攤開設計圖。
所以會議室支援的工作是在能短時間做好,而不需要實體支援的類型──不要硬體、不要圖表,沒有你不能捲起來帶著走的東西。也許有網路線,但要接上哪個區域網路呢?網路品質還不錯吧?接上筆記型電腦怎麼樣呢?有這些限制,會不會有開發人員和工程師覺得開會浪費時間呢?有標準規模的公司的實體架構明白地說,真正的工程都在小方塊裡做成的,而人都來到會議室則是他們沒有真在做事。企業的普通結構,沒有可以支援面對面溝通而能啟動系統設計的。
管理面對面的設計
一同有效地工作,意思是擁有在其中能真正工作的場所,讓許多人面對面地完成工作。也意味了賦與人們人際能力和流程,使他們的聚集比較有效。有一位部門主管指出一件棘手的問題,是在當地旅店訂房間讓五位資深架構師待著,並告訴他們,如果不在一週內提出解決方案,就要辭退他們。他得到結果,而我們發現如果人們有合理的工作過程,通常會比較快樂、有創造力,並且更快產生結果。對程序的典型回應是「感謝你,我現在終於知道該做什麼。」即使痛恨程序的人也會這麼說。
一起工作是一種新技能。是學校沒教的事,也是工作很少教的事。一起有效地工作,意味要懂得怎麼時常維持設計方面的對話,要怎麼用心到工作要項而不是其他事情上,要怎麼掌控每個人的特質,還有要怎麼發現並指出歧見的根本原因。如果團隊不這樣做,他們的工作就會因為人們處理歧見的模式與保持他們愉快的工作凝聚力之間的取決,而遭受損失。
人們處理歧見的一種主要的模式是政治交易:「我覺得你弄錯了。但是,如果你給我一些對我來說比較重要的東西,我就容得了你。」政治交易帶出一套以拼湊為主的系統,缺少具備向心力的主題。而且政治交易讓團隊的每個人都減少對設計工作投注心力,因為每一位都至少要認同一個人的決定,而他認為那個決定是錯的。
也有其他處理歧見的方法,但是大都不夠好。有一種方法是妥協,說:「你說我們要把什麼都做成對話方塊,但我覺得應該要做成按鈕才對。所以,兩種都做,我們誰都高興了。」誰都高興了,不過使用者不高興。他們有一打達到功能的辦法,但是沒有好的理由說明哪個辦法比較好。或者,會有教師式的歧見處理方式,說:「大師最聰明,而且什麼都懂。我們要跟著做大師所說的。」這很好,但除了在科技環境、圖形使用者介面設計、使用者實際工作、行銷、專案規劃、以及其他能力方面,這些絕對不錯的大師們所佔的人口數少到幾乎沒有。
情境設計 (Contextual Design) 規定一種發展系統的過程,可以帶出人際技能的價值。規定了根據資料來取捨各種開發選項,所參考的資料不包括爭議和政治交易。情境設計規定了人該扮演的角色,能在設計的過程中一直保持討論。不但要讓設計的過程比較有效率,還要因為人們爭議並沒有進展而將系統暫時擱到一邊。
前端系統設計讓我們著眼於人際的課題,因為設計程序的這一部份會帶來由面對面影響得很深的不一樣的功能。傳統的設計較不帶出著重在一起工作的技能。致力於保持客戶工作的凝聚力,而排除團隊中不同的看法和不同的能力,會使認知到如何一起工作變得很重要。我們發現,在人們該進行明確的流程、扮演明確的角色時,那時他們會對個人風格很敏感,使他們在房間裡起衝突。而當他們有具體的資料可以根據以設定決策,就會跨過隔籬,一起有效地工作。
這就是以客戶為中心的意義:不只做到客戶導向的設計,還要讓設計流程將系統帶往能讓客戶的工作──從開始到實作──能凝聚在系統中。對情境設計的挑戰是內建在方法中,要瞭解一同工作的要點,還要提供有效工作的辦法。
Wednesday, May 13, 2009
MSN換暱稱 相關行銷活動資訊
<AION封測。與你相約>將您的 MSN 暱稱更改為 "是我唯一的選擇!", 就有機會得到 CB 帳號哦!!
http://buboo.tw/msg/00a05b01a85d24c.html
王品msn步步大串連活動
http://www.wangsteak.com.tw/event/09_walk/fight_2_MSNatt.aspx
msn友達大募集
http://www.9inthebox.com.tw/campaign/event/200904/mem/index.php
http://buboo.tw/msg/00a05b01a85d24c.html
王品msn步步大串連活動
http://www.wangsteak.com.tw/event/09_walk/fight_2_MSNatt.aspx
msn友達大募集
http://www.9inthebox.com.tw/campaign/event/200904/mem/index.php
設計的挑戰──在與客戶保持聯係方面
本文翻譯 Contextual Design 一書 (Amazon 記錄) 第 9 頁 (Google Books 預覽): The Challenge For Design - Keeping in Touch with the Customer 。
文中有下列角色:
設計團隊: design team ,就是開發人員。
開發人員: developers ,就是設計團隊或設計者。
企業: business ,就是客戶、提出需求和出資的公司。
資訊科技部門: IT department ,就是今日名上有「資訊」、「科技」等字眼的公司。
角色: role ,就是在資訊科技部門或企業中,有各種不同的職稱、做不同工作的人。
設計的挑戰──在與客戶保持聯係方面
如果從密切瞭解客戶方面出發、來做設計,是最基本的事,為什麼那麼難做到呢?產品開發公司發起的時候,他們創造了讓設計者與客戶分隔的組織方式。剛開始是要設計者由與潛在的客人對談,以幫助銷售。但是當公司成長了,就發展出銷售部門做應對客戶的介面;安插了操作代表 (account representative) 控制業務部門;安差了行銷和產品管理部門。這些走向使設計者甚至和銷售人員分隔了。剛開始是把設計者擺在客戶服務線上。但是當公司成長了,有一個完整部門搞定客戶服務任務,還有正規的介面對開發工作提出回饋意見。開發者被孤立,無法直接接到客戶回報他們工作的好壞。我們跟一些開發人員談過,他們與客戶之間真是孤立;在另一方面感到無力的是,因為覺得自己無法修正客戶發現的問題,他們甚至不想跟客戶談談。
資訊科技部門有一個不同的理由對駐留在客戶那邊感到有困難。在公司成長時,他們也是動輒與客戶分隔,但可行的不同方式都伴隨著問題而來。他們創造新角色──商務、系統、或需求分析人員──在客戶和開發者之間做翻譯,卻發現客戶仍相信資訊科技部門不了解他們的東西。其他的角色則不和客戶創造有密切工作關係,也不為了開發人員創造無阻礙的不干涉局面。
為了控制變動的需求,資訊科技部門做了收尾舉動,但是客戶的優先順序和需求還在改變。因此他們把開發人員安排在所服務支援的企業人員身邊,就可以就近影響企業的工作。他們弄好了客戶關係,卻意味了資訊科技部們不能分享資源和專業,也不能做為看穿整個企業資訊系統的關鍵角色。所以,他們決定他們太沒組織了,就把人都再拉回來,並重新導出了孤立的問題。
在資訊科技部門,這種震盪是個典型,但是終究錯失重點。任何對人的安排都跟著伴隨著問題,所以唯一的解決辦法是瞭解問題並加以處理。資訊科技部門需要和客戶保持一些距離,以看清不同部門之間造成的衝突,並規劃系統將企業視為整理來處理問題 (連同對系統出資的方式)。同時,他們需要讓他們和客戶保持密切夥同關係的機制。
以上就是情境設計 (Contextual Design) 的挑戰:要讓設計團隊明瞭他們的客戶,要給他們足夠的距離能以整體觀──能看透企業或看透一個市場──來看工作的實務。這個過程同時還要讓設計團隊徹底以「什麼是對客戶較實在」的知識做為基礎。
文中有下列角色:
設計團隊: design team ,就是開發人員。
開發人員: developers ,就是設計團隊或設計者。
企業: business ,就是客戶、提出需求和出資的公司。
資訊科技部門: IT department ,就是今日名上有「資訊」、「科技」等字眼的公司。
角色: role ,就是在資訊科技部門或企業中,有各種不同的職稱、做不同工作的人。
設計的挑戰──在與客戶保持聯係方面
如果從密切瞭解客戶方面出發、來做設計,是最基本的事,為什麼那麼難做到呢?產品開發公司發起的時候,他們創造了讓設計者與客戶分隔的組織方式。剛開始是要設計者由與潛在的客人對談,以幫助銷售。但是當公司成長了,就發展出銷售部門做應對客戶的介面;安插了操作代表 (account representative) 控制業務部門;安差了行銷和產品管理部門。這些走向使設計者甚至和銷售人員分隔了。剛開始是把設計者擺在客戶服務線上。但是當公司成長了,有一個完整部門搞定客戶服務任務,還有正規的介面對開發工作提出回饋意見。開發者被孤立,無法直接接到客戶回報他們工作的好壞。我們跟一些開發人員談過,他們與客戶之間真是孤立;在另一方面感到無力的是,因為覺得自己無法修正客戶發現的問題,他們甚至不想跟客戶談談。
資訊科技部門有一個不同的理由對駐留在客戶那邊感到有困難。在公司成長時,他們也是動輒與客戶分隔,但可行的不同方式都伴隨著問題而來。他們創造新角色──商務、系統、或需求分析人員──在客戶和開發者之間做翻譯,卻發現客戶仍相信資訊科技部門不了解他們的東西。其他的角色則不和客戶創造有密切工作關係,也不為了開發人員創造無阻礙的不干涉局面。
為了控制變動的需求,資訊科技部門做了收尾舉動,但是客戶的優先順序和需求還在改變。因此他們把開發人員安排在所服務支援的企業人員身邊,就可以就近影響企業的工作。他們弄好了客戶關係,卻意味了資訊科技部們不能分享資源和專業,也不能做為看穿整個企業資訊系統的關鍵角色。所以,他們決定他們太沒組織了,就把人都再拉回來,並重新導出了孤立的問題。
在資訊科技部門,這種震盪是個典型,但是終究錯失重點。任何對人的安排都跟著伴隨著問題,所以唯一的解決辦法是瞭解問題並加以處理。資訊科技部門需要和客戶保持一些距離,以看清不同部門之間造成的衝突,並規劃系統將企業視為整理來處理問題 (連同對系統出資的方式)。同時,他們需要讓他們和客戶保持密切夥同關係的機制。
以上就是情境設計 (Contextual Design) 的挑戰:要讓設計團隊明瞭他們的客戶,要給他們足夠的距離能以整體觀──能看透企業或看透一個市場──來看工作的實務。這個過程同時還要讓設計團隊徹底以「什麼是對客戶較實在」的知識做為基礎。
Tuesday, May 12, 2009
Erlang gen_server 行為解析
本文為翻譯 gen_server behaviour in Erlang (http://geeklair.net/~pratzsch/blog/2008/04/gen-server-behaviour-in-erlang.html)一篇.
授權聲明:本篇是由 Phil Ratzsch 發表於個人 blog 「你不愛讀的東西」(You dont't want to read this. http://geeklair.net/~pratzsch/blog/) ,文章發表於 2008 年 4 月 30 日晚間。我已透過電子郵件徵求取得作者許可,在此張貼翻譯版本。非常感謝 Philip Ratzsch 閣下。
Claim: This article by Phil Raztsch is posted in his blog "You dont' want to read this" in the evening at April 30, 2008. I've got the author's permission that allows me to post my translated version. I would like to convey thanks to Mr. Philip Ratzsch.
標色文字是我的註解。
Erlang gen_server 行為解析
本文由 Phil Ratzsch 於 2008 年 4 月 30 日晚間發表
你們有些自己在家玩些什麼 (我說:宅男嗎?) 的人都知道我有點喜歡 Erlang 全部的東西。對啊!你們一些在家玩自己的 (還有任性的衝浪人,也是) 、與歐洲的戶外隔離的人,可能想知道為什麼 behaviour 字裡躲著一個煩人的 u 字母。 Erlang 來自 Ericsson 公司 (他們公開否認 Erlang 和 Ericsson Language 一詞的關係,而說 Erlang 跟著一位同名數學家的名字定名) 而且 Ericsson 正好位於 Scandanavia 地區。 (據查:Scandanavia 是北歐包含丹麥、瑞典和挪威三國的區域)
語言家的理論說可以隨他們喜好、用 u 代替「 o 中間劃一線」字母。 (我說:那是一個丹麥文字母 Ф ,做母音有時音同 bird 或 hurt 、有時音同 sister 的 i 音。) 或是可能他們想表現出多麼愛那個空集合符號。不管這個,我們跳進 gen_server 話題吧。
gen_server 是 OTP ──「公開電傳平台」(Open Telecom Platform) ── 的一項元件。 OTP 可說是 Erlang 的一種應用程式架構。像 Python (蟒蛇) 有 Pylons (高壓電線架) ,以及 Ruby (寶石) 有 Rails (軌道或扶手) ,還有 Windows 有「當機的毛病」。 OTP 有強大威力,令人喜不自禁;而身為相當新手的我,只開始領會它有多強。引述 Joe Armstrong 寫的 "Programming Erlang" 書中字句:
舉一個很傳統的人為範例,假想一家錄影帶店只讓你一次買一部片。程式碼可能看起來像下列我收錄的。像上次一樣,先來個程式,再來個說明。我無限地感謝執行 CouchDB 專案的主持人 Jan Lehnardt 的幫助、耐心指導和友誼。將來不久,他也會貼一筆同樣主題的 plok 記錄,所以請務必去看一下,而且要給他錢。 (我說: plok 是很像 blog 的東西。)
好,看起來很龐大 (順便地說,也是 Erlang 的超級威力) 但其實不是。第一行宣告了模組名稱 (而且 movie_store.erl 必須是檔名),這是 Erlang 每個程式都有的標準格式。
-behaviour(gen_server). 可想成是宣告我們程式裡用什麼「模版」。 gen_server 的行為要求我們要定義列在第一組匯出 (exports) 的函數。
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). 是 gen_server 匯出並尋找的函數 (,而且如果缺了他們,可會抱怨得很大聲喔) 。下篇文章我會探究它們、深入到細節 (我說:但他的下一篇文章,我不見得會譯完。) ,恰如這會是一篇長篇大作。現在,要曉得,就算這些函數都不做事情,也要定義這些函數全部。如你所見,尾端一些程式像 handle_cast/2 、 handle_info/2 、 terminate/2 、 code_change/3 ,都不做事情。
-export([checkout/2, lookup/1, start_link/0]). 製做自訂的函數,讓 server 可使用它們於外界。這些函數列在另一個 -export 敘述中,以資區別,或者也可以與前面的 -export 合併。
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
程式的起點。如你所見,這個函數是 server 運作命令的包裝。{local, ?MODULE} 顯示 server 會以區域方式執行,並不會讓叢集系統的其他 Erlang 節點存取。 ?MODULE 是現有程式的替身,指示我們該用什麼東西參考這個 server 。第二個 ?MODULE 告訴 server 往哪裡找到 callback (在此例是同一個檔案) 。其他選項容許開啟除錯功能、做檔案記錄、以及其他未列入此例的項目。
checkout(Customer, Movie) -> gen_server:call(?MODULE, {checkout, Customer, Movie}).
lookup(Customer) -> gen_server:call(?MODULE, {lookup, Customer}).
這幾行聯繫自訂函數,告訴 gen_server 當 movie_store:checkout(...) 和 movie_store:lookup(...) 函數呼叫時能做什麼。 ?MODULE 指定函數所在的檔案和模組,而 {some_name, Arg1, Arg2, ...} 提供函數名稱和傳入的參數。
checkout(Customer, Movie) -> gen_server:call(?MODULE, {checkout, Customer, Movie}).
第一個項目符合樣式 (我說:指 {checkout, Customer, Movie} ) ,這是 gen_server 知道如何處理 handle_call 呼叫 ... 那個 ... 呼叫。嗯,最後一截用太多「處理」和「呼叫」的字眼了。重點是就像其他許多 Erlang 的東西一樣,以符合樣式為基礎。
注意一下, Tab 表格也傳入了。我們就進到一個 case/of 段落,檢查客戶在表格中有沒有購買了影片。如果沒找到記錄 ([] -> ...) ,片子就賣給他們,在此段落傳回 {ok, 影片名稱} 。如果已經有記錄,則傳回 {already_checked_out, 另一影片名稱} 並拒絕客人購買片子。 (注意,本例沒有讓客人退貨的辦法。這個留給讀者你自己練習。)
本段落任何一個情況都將傳回值塞進一列記錄,發射回給呼叫這個函數的人。在往下一個 handle_call(...) 走去之前,看一下最後一行: {reply, Response, Tab}; 。你可能期待有個句點而不是分號。 handle_call(...) 句子是用分號結尾,而且如果是改用像其他函數一樣的結尾。我好不容易才找到它的道理。 (我說:分號表示同一函數的兩套不同的定義之間的分界。)
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVersion, State, _Extra) -> {ok, State}.
這段程式要擺在那邊,使 gen_server 能動;但這次我們沒用到它們。下一篇導引文章我會多談談。但我簡短說明: code_change/3 超酷,它讓 server 還在服務的時候可以將程式內容做熱抽換。要知道,想要改換程式何必麻煩讓 server 停掉呢,是吧?
最後,這是如何執行的示範:
2> c(movie_store).
{ok,movie_store}
3> movie_store:start_link().
{ok,<0.42.0>}
4> movie_store:checkout(phil, "Sneakers").
{ok,"Sneakers"}
5> movie_store:lookup(phil).
"Sneakers"
6> movie_store:checkout(phil, "Koyaanisqatsi").
{already_checked_out, "Sneakers"}
7> movie_store:lookup(phil).
"Sneakers"
(我說: 2 號命令是編譯 move_store.erl 。 3 號命令呼叫 movie_store:start_link(...) ,它轉呼叫 gen_server:start_link(...) 得到 {ok, <0.42.0>} ,表示命令完成,<0.42.0> 是 server 的程序代號。 Koyaanisqatsi (印地安語,意思是 life out of balance ,失衡的人生) 是一部藝術片,參考 IMDB 條目 (http://www.imdb.com/title/tt0085809/) 和 Wikipedia 條目 (http://en.wikipedia.org/wiki/Koyaanisqatsi) 可知道更多資訊。)
有個問題是程式在你試著選購 Koyaanisqatsi 時不會對你恭維幾句。嗯,我已經太煩人一整天了,至少希望你感興趣。如果你們要改就全都改,或者無論如何務必讓我知道。
建言:
Ulf Wiger 在 2008 年 5 月 1 日上午,說:
丹麥人和挪威人才用 o 中間砍一線,而瑞典人沒有這樣做。咱們都用 Ö 和 Ä ,很像德國人用的,但又多了很美的字母 Å 。對丹麥數學家致敬不代表分擔了使用 Ø 的原罪。 Erlang /OTP 團隊充斥著英國人,英文 behaviour 的拼字法可能源於那邊 ...
但不全沒有。若要建立自訂的行為, linter 接受 -behaviour() 和 -behavior() 兩種,還有 -behaviour_info() 和 -behavior_info() 。
還有,我聽說 Joe Armstrong (英格蘭人) 、 Mike Willams (威爾斯人) 、 Robert Virding 以前住在澳大利亞。
Harishi Mallipeddi 在 2008 年 5 月 2 日近午,說:
OTP Design Principles 一篇提供很有用 (至少對我來說) 的學習方法,學會用 OTP 的東西,包括 gen_server 、 gen_fsm 、其他等等。 Joe 的書可沒好好解釋 OTP 。
http://www.erlang.org/doc/design_principles/part_frame.html
授權聲明:本篇是由 Phil Ratzsch 發表於個人 blog 「你不愛讀的東西」(You dont't want to read this. http://geeklair.net/~pratzsch/blog/) ,文章發表於 2008 年 4 月 30 日晚間。我已透過電子郵件徵求取得作者許可,在此張貼翻譯版本。非常感謝 Philip Ratzsch 閣下。
Claim: This article by Phil Raztsch is posted in his blog "You dont' want to read this" in the evening at April 30, 2008. I've got the author's permission that allows me to post my translated version. I would like to convey thanks to Mr. Philip Ratzsch.
標色文字是我的註解。
Erlang gen_server 行為解析
本文由 Phil Ratzsch 於 2008 年 4 月 30 日晚間發表
你們有些自己在家玩些什麼 (我說:宅男嗎?) 的人都知道我有點喜歡 Erlang 全部的東西。對啊!你們一些在家玩自己的 (還有任性的衝浪人,也是) 、與歐洲的戶外隔離的人,可能想知道為什麼 behaviour 字裡躲著一個煩人的 u 字母。 Erlang 來自 Ericsson 公司 (他們公開否認 Erlang 和 Ericsson Language 一詞的關係,而說 Erlang 跟著一位同名數學家的名字定名) 而且 Ericsson 正好位於 Scandanavia 地區。 (據查:Scandanavia 是北歐包含丹麥、瑞典和挪威三國的區域)
語言家的理論說可以隨他們喜好、用 u 代替「 o 中間劃一線」字母。 (我說:那是一個丹麥文字母 Ф ,做母音有時音同 bird 或 hurt 、有時音同 sister 的 i 音。) 或是可能他們想表現出多麼愛那個空集合符號。不管這個,我們跳進 gen_server 話題吧。
gen_server 是 OTP ──「公開電傳平台」(Open Telecom Platform) ── 的一項元件。 OTP 可說是 Erlang 的一種應用程式架構。像 Python (蟒蛇) 有 Pylons (高壓電線架) ,以及 Ruby (寶石) 有 Rails (軌道或扶手) ,還有 Windows 有「當機的毛病」。 OTP 有強大威力,令人喜不自禁;而身為相當新手的我,只開始領會它有多強。引述 Joe Armstrong 寫的 "Programming Erlang" 書中字句:
OTP 的能力來自於一些特性,諸如容錯、可延伸能力、以及動態碼的更新等等,都由它的行為提供。也就是說,寫 callback 的程式人不用煩這些事情了,因為 OTP 行為會提供這些能力。好的,菲利普,「行為」是指什麼呢?一件行為,就是像它聽起來像是的東西 ── 像一個桶子裝了一種系統或平台的全部普通行為。 (我說:這到底是什麼樣的直覺?)
舉一個很傳統的人為範例,假想一家錄影帶店只讓你一次買一部片。程式碼可能看起來像下列我收錄的。像上次一樣,先來個程式,再來個說明。我無限地感謝執行 CouchDB 專案的主持人 Jan Lehnardt 的幫助、耐心指導和友誼。將來不久,他也會貼一筆同樣主題的 plok 記錄,所以請務必去看一下,而且要給他錢。 (我說: plok 是很像 blog 的東西。)
-module(movie_store).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([checkout/2, lookup/1, start_link/0]).
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
checkout(Customer, Movie) -> gen_server:call(?MODULE, {checkout, Customer, Movie}).
lookup(Customer) -> gen_server:call(?MODULE, {lookup, Customer}).
init([]) ->
Tab = ets:new(?MODULE, []),
{ok, Tab}.
handle_call({checkout, Customer, Movie}, _From, Tab) ->
Response = case ets:lookup(Tab, Customer) of
[] ->
ets:insert(Tab, {Customer, Movie}),
{ok, Movie};
[{Customer, OtherMovie}] ->
{already_checked_out, OtherMovie}
end,
{reply, Response, Tab};
handle_call({lookup, Customer}, _From, Tab) ->
Reply = case ets:lookup(Tab, Customer) of
[{Customer, Movie}] ->
Movie;
[] ->
none
end,
{reply, Reply, Tab}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVersion, State, _Extra) -> {ok, State}.
好,看起來很龐大 (順便地說,也是 Erlang 的超級威力) 但其實不是。第一行宣告了模組名稱 (而且 movie_store.erl 必須是檔名),這是 Erlang 每個程式都有的標準格式。
-behaviour(gen_server). 可想成是宣告我們程式裡用什麼「模版」。 gen_server 的行為要求我們要定義列在第一組匯出 (exports) 的函數。
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). 是 gen_server 匯出並尋找的函數 (,而且如果缺了他們,可會抱怨得很大聲喔) 。下篇文章我會探究它們、深入到細節 (我說:但他的下一篇文章,我不見得會譯完。) ,恰如這會是一篇長篇大作。現在,要曉得,就算這些函數都不做事情,也要定義這些函數全部。如你所見,尾端一些程式像 handle_cast/2 、 handle_info/2 、 terminate/2 、 code_change/3 ,都不做事情。
-export([checkout/2, lookup/1, start_link/0]). 製做自訂的函數,讓 server 可使用它們於外界。這些函數列在另一個 -export 敘述中,以資區別,或者也可以與前面的 -export 合併。
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
程式的起點。如你所見,這個函數是 server 運作命令的包裝。{local, ?MODULE} 顯示 server 會以區域方式執行,並不會讓叢集系統的其他 Erlang 節點存取。 ?MODULE 是現有程式的替身,指示我們該用什麼東西參考這個 server 。第二個 ?MODULE 告訴 server 往哪裡找到 callback (在此例是同一個檔案) 。其他選項容許開啟除錯功能、做檔案記錄、以及其他未列入此例的項目。
checkout(Customer, Movie) -> gen_server:call(?MODULE, {checkout, Customer, Movie}).
lookup(Customer) -> gen_server:call(?MODULE, {lookup, Customer}).
這幾行聯繫自訂函數,告訴 gen_server 當 movie_store:checkout(...) 和 movie_store:lookup(...) 函數呼叫時能做什麼。 ?MODULE 指定函數所在的檔案和模組,而 {some_name, Arg1, Arg2, ...} 提供函數名稱和傳入的參數。
init([]) ->用 ets 建立資料表並傳回。 ets 是內建的記憶體資料庫。在部署的程式中,這或許有時有些 ... 耐久。 gen_server 的關鍵元件是程式狀態。在本例中,你將看到 Tab 被丟來丟去,丟到每一樣程式單元中,表達現有的錄影帶店狀態 (誰購買了什麼片) 。
Tab = ets:new(?MODULE, []),
{ok, Tab}.
handle_call({checkout, Customer, Movie}, _From, Tab) ->
Response = case ets:lookup(Tab, Customer) of
[] ->
ets:insert(Tab, {Customer, Movie}),
{ok, Movie};
[{Customer, OtherMovie}] ->
{already_checked_out, OtherMovie}
end,
{reply, Response, Tab};
記得之前說的一點 gen_server:call(...) 嗎?這是 gen_server 呼叫的東西。你們可能想知道為什麼 handle_call 定義了二個函數,而且引用相同數量的參數 (參數數量表達為 /x ,如 "functioname/2" 裡面的 /2 ) 。看它第一個參數,是有三項的一列記錄。再看看checkout(Customer, Movie) -> gen_server:call(?MODULE, {checkout, Customer, Movie}).
第一個項目符合樣式 (我說:指 {checkout, Customer, Movie} ) ,這是 gen_server 知道如何處理 handle_call 呼叫 ... 那個 ... 呼叫。嗯,最後一截用太多「處理」和「呼叫」的字眼了。重點是就像其他許多 Erlang 的東西一樣,以符合樣式為基礎。
注意一下, Tab 表格也傳入了。我們就進到一個 case/of 段落,檢查客戶在表格中有沒有購買了影片。如果沒找到記錄 ([] -> ...) ,片子就賣給他們,在此段落傳回 {ok, 影片名稱} 。如果已經有記錄,則傳回 {already_checked_out, 另一影片名稱} 並拒絕客人購買片子。 (注意,本例沒有讓客人退貨的辦法。這個留給讀者你自己練習。)
本段落任何一個情況都將傳回值塞進一列記錄,發射回給呼叫這個函數的人。在往下一個 handle_call(...) 走去之前,看一下最後一行: {reply, Response, Tab}; 。你可能期待有個句點而不是分號。 handle_call(...) 句子是用分號結尾,而且如果是改用像其他函數一樣的結尾。我好不容易才找到它的道理。 (我說:分號表示同一函數的兩套不同的定義之間的分界。)
handle_call({lookup, Customer}, _From, Tab) ->
Reply = case ets:lookup(Tab, Customer) of
[{Customer, Movie}] ->
Movie;
[] ->
none
end,
{reply, Reply, Tab}.
這個 handle_call/3 定義一個函數檢查看看客人有沒有購買了影片。如果有,傳回一筆記錄包含了客人和電影的名字。如果沒有,則傳回 none 。 (我說:重講一次,應該說是找得到一筆記錄符合 {Customer, Movie} 就傳回電影名稱,否則,如果找不到就傳回 none 。) 我不要講這個太多,因為以正在講的 handle_call/3 來說,這個東西太細。handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVersion, State, _Extra) -> {ok, State}.
這段程式要擺在那邊,使 gen_server 能動;但這次我們沒用到它們。下一篇導引文章我會多談談。但我簡短說明: code_change/3 超酷,它讓 server 還在服務的時候可以將程式內容做熱抽換。要知道,想要改換程式何必麻煩讓 server 停掉呢,是吧?
最後,這是如何執行的示範:
2> c(movie_store).
{ok,movie_store}
3> movie_store:start_link().
{ok,<0.42.0>}
4> movie_store:checkout(phil, "Sneakers").
{ok,"Sneakers"}
5> movie_store:lookup(phil).
"Sneakers"
6> movie_store:checkout(phil, "Koyaanisqatsi").
{already_checked_out, "Sneakers"}
7> movie_store:lookup(phil).
"Sneakers"
(我說: 2 號命令是編譯 move_store.erl 。 3 號命令呼叫 movie_store:start_link(...) ,它轉呼叫 gen_server:start_link(...) 得到 {ok, <0.42.0>} ,表示命令完成,<0.42.0> 是 server 的程序代號。 Koyaanisqatsi (印地安語,意思是 life out of balance ,失衡的人生) 是一部藝術片,參考 IMDB 條目 (http://www.imdb.com/title/tt0085809/) 和 Wikipedia 條目 (http://en.wikipedia.org/wiki/Koyaanisqatsi) 可知道更多資訊。)
有個問題是程式在你試著選購 Koyaanisqatsi 時不會對你恭維幾句。嗯,我已經太煩人一整天了,至少希望你感興趣。如果你們要改就全都改,或者無論如何務必讓我知道。
建言:
Ulf Wiger 在 2008 年 5 月 1 日上午,說:
丹麥人和挪威人才用 o 中間砍一線,而瑞典人沒有這樣做。咱們都用 Ö 和 Ä ,很像德國人用的,但又多了很美的字母 Å 。對丹麥數學家致敬不代表分擔了使用 Ø 的原罪。 Erlang /OTP 團隊充斥著英國人,英文 behaviour 的拼字法可能源於那邊 ...
但不全沒有。若要建立自訂的行為, linter 接受 -behaviour() 和 -behavior() 兩種,還有 -behaviour_info() 和 -behavior_info() 。
還有,我聽說 Joe Armstrong (英格蘭人) 、 Mike Willams (威爾斯人) 、 Robert Virding 以前住在澳大利亞。
Harishi Mallipeddi 在 2008 年 5 月 2 日近午,說:
OTP Design Principles 一篇提供很有用 (至少對我來說) 的學習方法,學會用 OTP 的東西,包括 gen_server 、 gen_fsm 、其他等等。 Joe 的書可沒好好解釋 OTP 。
http://www.erlang.org/doc/design_principles/part_frame.html
Monday, May 11, 2009
(msn機器人)當RFID 遇見 愛慕MSN機器人
詳細文章可見 http://www.ithome.com.tw/itadm/article.php?c=54654
IMOO MSN/GTALK 機器人研發團隊 針對企業及醫療產業提供優質的RFID整合MSN機器人加值應用解決方案,架構於綿密的產業網路脈絡上,分佈於複雜的產業供應鏈中,幫助各大產業快速整合現有IT系統資源,有效降低營運成本、徹底提昇管理效能,讓RFID系統整合加值應用為產業帶來真正簡單、實用、安全的智慧科技。
RFID企業應用解決方案-「全球化IP身份辨識管理」系統採用網際網路TCP/IP架構,支援全球化Web Service應用,透過與總部ERP/HIS等後端系統連接,整合MSN訊息通知平台,將相關事件通知隨著使用者服務到全球,並配合智慧型PDA手機達成遠端控管及通知。全系統採用集權分層式管理,簡單又快速的將人、卡、設備的權限管理彙整於同一套系統中,透過網路進行無國界線上即時管理,快速整合後台(門禁/差勤/視訊對講/影印列印漫遊/電子錢包…等)其他應用需求,讓「人」的管理變的很簡單。
Monday, April 6, 2009
規則式系統的系統描述
本篇來講一些規則系統(production system, rule-based sytem, or expert sytem)的系統描述(formulation)。規則系統是由工作空間(包含事實)、知識庫(包含規則)、以及推論引擎(包含推論及控制流程)等三樣東西構成。一般大學教科書中,很少明確說明規則系統的設計。而相關論文則都使用 Lisp 語言介紹系統架構,較近年代的程式人員根本看不懂。
1. 程序代數
所以,用一些形式語言說明規則系統的架構。推論引擎包含三個分開的程序,所以我們用到基本程序代數(Pi Calculus):令 p, q 是二個程序,二個程序的結構可能是下列其中一種樣子。
p, q ::= a(c) . p (輸入)
| a! c . p (輸出)
| a! c . p (輸出)
| P | q (平行處理)
| if x = y then p else q (條件控制)
| rec z . p (遞迴)
| stop (終止)
上述項目的意義是:
- a(c) . p 是程序 p 要從 a 通訊管道取得一些資料 c ;
- a! c . p 是程序 p 要對 a 通訊管道送出一些資料 p ;
- p | q 是二個程序 p, q 平行地執行;
- if x = y then p else q 是先比較二項資料 x 和 y ,如果 x = y 就執行程序 p ,否則執行程序 q ;
- rec z . p 是將程序 p 定義為一個遞迴程序,以 z 標示。在 p 中存在 z 符號,表示遞迴呼叫;
- stop 是一個終止程序。
我們說, P <= a(b) . p 是定義一個程序 P 的內容是, p 知道一 通訊管道 a 並 管道 a 取出資料
b 。為了方便,用 P(a) 表示此式,即程序 P 一開始就知道通訊管道 a ,並可以隨意使用。
2. 基本詞彙
另外,我們需要一些基本符號,列舉如下:
單元詞彙:要表示一個資料單位或一項物件,用小寫字母 a, b, ..., z 表示任何一個單元。
集合詞彙:用大寫字母 A, B, ..., Z 表示任何一個集合。每一個集合中包含了許多單元。所以,x < X 表示一個單元詞彙 x 屬於另一個集合 X 。
邏輯式或敘述:用一些單元詞彙和一些邏輯運算符號 & , | , ~ , -> 等等,組合成另一些字串,這些字串稱為邏輯式、或稱為敘述:例如,有單元詞彙 x, y ,則 x & y 是一則敘述、 ~x 是一則敘述、並 (x & y -> x) | (x & y -> y) 也是一則敘述。在本篇文章,我們要用到許多 -> 運算符號。
隱含( -> ):是一種邏輯運算符號,用來表示符號的左項和右項之間有因果關係:例如,對單元詞彙 x, y 來說, x -> y 是一則敘述,其意義是
x y x -> y
true true true
true false false
false true true
fase false true
只有當 x 有效但 y 無效時, x -> y 不能成立。這稱為「 x 隱含 y 」、「 x 代表 y 」。
例外詞彙:任何其他用途的詞彙,都用粗體大寫字母 A, B, ..., Z 表示:例如,用 M 表示一則程序。
Lambda函數:是一種匿名函數的表示法,以格式為「 入 a b c ... . p(a, b, c, ...) 」的字串表示一則函數。其中,「入」是希臘文字母,唸 lambda ;「入」之後是一些參數、之後是一點、之後是函數內容:例如, 入x y . x + y 是一則匿名函數,接受二項參數而計算總和。
3. 定義
事實:用一個單元詞彙表達一項事實:例如,用 x 表達「今天下雨」。
規則:用一則格式為「 a & b & ... -> a & b & ... 」的邏輯式,表示一條規則:例如 a & b -> c & d 。其中, -> 符號左邊稱為左手側,常用英文 LHS 表示;右邊稱為右手側,常用英文 RHS 表示。左手側就是規則條件,而右手側就是規則的結論。
規則系統:是一組結構 <F, R, M, C, A > ,其中組成單元有:
- F :一些事實的集合。
- R :一些規則的集合。
- M :規則比對程序,負責將一些事實和一些規則彼此比對,然後選出符合比對的規則,當做結果。
- C :協調程序,負責將 M 的結果做衝突協議(Conflict Resolution)。衝突協議是在一些規則中,只挑選一些必須啟動的規則,當做結果;並排除彼此衝突或互相重覆的規則:例如,規則 A & B -> C 和規則 A -> C 重覆,因為前者的規則條件是後者的子集合。 Rete 演算法規定,對這二條規則,要選擇 A & B -> C ,因為規則條件比較嚴格。
- A :行動程序,負責將 C 的結果── 一些確定要啟動的規則 ──確實執行。 A 要將 C 結果的右手側取出並執行。
Rete 結構: Rete 演算法是討論一些規則的集合應該如何組織、並組織一種有效的結構,使事實和規則彼此比對變的比較有效。令有一些規則為 R = { A & B -> C , B & C -> D } ,根據最初的 Rete 演算法論文, R 有一組對應的 rete 結構,令為 R(R) 。 R(R) 包含一些流程控制,定義為
入 f . R(R) ::=
入 f . if type(f) = A then assert(C(_^B)) ;
if type(f) = B then assert(C(A^_)); assert(D(_^C)) ;
if type(f) = C then assert(D(B^_)) ;
if assert(C(_^B)) and assert(C(A^_)) then match(A & B -> C) ;
if assert(D(_^C)) and assert(C(B^_)) then match(B & C -> D)
在 R(R) 中由三種節點構成,包括 type(f) = A 檢查輸入事實的 type 屬性、 assert(C(A^B)) 表示結果 C 是由 A & B 決定、以及 match(r) 指明條件 r 已經符合比對。而 C(_^B) 表示 C 的一則決定項已經接受、並等待另一則決定項 B 。
4. 推論引擎
推論引擎包含 M, C, A 三項程序,依序循環使用。我們用程序代數和上述符號標記法定義三項程序。
取比對程序 M 為
M(a, b) <= rec z . a(f1, (f2, f*)) . ((入 f . R(R)) f1 | a! f2, f* . z )
其中 (f1, (f2, f*)) = F = (f1, f2, ..., fn) ,並且 (入 f . R(R)) f1 是一則匿名函數代入參數而生效,計算方式是 R(R)[f1/f] 、即把函數主體 R(R) 中存在的 f 替換為 f1 。在 R(R) 中的 match 定義為
match(b) <= b! r . stop
又取協調程序 C 為
C(b, c) <= rec z . b(r1, (r2, r*)) . ( if r1 = empty then stop
else
if forall r < R . r1 >= r then fire(r1)
| b! r2, r* . z )
其中, r1 > r 是一條規則對另一條規則的大於關係,定義為 LHS(r1) < LHS(r) 則 r1 > r ,並且 fire(LHS -> RHS) <= c! RHS . stop 。
又取行動程序 A 為
A(c, d) <= rec z . c(rhs1, (rhs2, rhs*)) . d! rhs1 . c! rhs2, rhs* . z
於是,推論引擎取為
INF(a) <= rec z . a(F, R) . (M(a, b) | C(b, c) | A(c, d) | d(F') . a! (F+F'), R . z)
嗯?有點錯誤,管它的,只是個思考過程。
Subscribe to:
Posts (Atom)