剛好聊到系統設計想到,對很多開發人員的經驗而言,防呆是很重要的事情,把使用者當笨蛋,確保系統只接收到控制範圍內的輸入。而我的做法恰恰是反其道而行。
每個界面開發人員都認為自己在開發「好的使用體驗」,但是大部份人在設計使用體驗的時候,都是無差別式的設計,也就是,不管做什麼界面,都是以 0 ~ 100 歲的任何人一開到就會用做標準。或至少是 9 歲 到 40 歲。這種設計理念我實在無法苟同,不止影響開發產出效率,同時也限制系統的發展。
我認為好的「使用體驗」,是要根據系統的目標族群,讓新手有足夠的資訊完成工作,老手有足夠的彈性加速工作,更甚者,使用者還能發明意想不到的用法。
在有限制對象的情況下,有時候最簡單的設計反而最好用
舉例來說,前陣子規劃一個員工考核系統,裏面建立員工資料的時候,要選填頭銜。一般開發者的做法,多半是資料庫有一個頭銜資料表,然後做一個新增,刪除,修改,排序用的界面給使用者使用。不過我這次就大膽的只給一個像留言板的空白框框,然後告訴使用者,一行一個頭銜,你想改排序,簡單,自己剪下貼到前面,然後存檔就好。
圖一:頭銜編輯界面
由於後台的使用者就那一兩位,這種界面他在編輯的時候,操作滑鼠鍵盤跟等待資料處理回應的次數超級少,所以打從一開始他使用就沒什麼問題。不過因為擔心他不小心全選刪除又不小心儲存,所以我們做了一個恢復上一個設定的功能,讓他可以隨心所欲的編輯。
至於這樣的界面的開發時間呢,恩,大概五到十分鐘吧,因為我們最後只把整個輸入框的字存成一個字串,所以也沒有資料表跟欄位處理的問題。
這麼瞎的界面我還做在我們產品,一個結帳系統銷售公司,會常常需要幫客戶預先建立該客戶完整的商品,且初期會常修改,需要能批次處理。對安裝工程師來講最親切的界面是Excel那樣可快速複製貼上,安排順序的界面,不過在Web做出來成本極高,因此我們索性(其實是偷懶)就放了一個空白輸入框,然後上方寫一個範例,說明請使用者按照 品名, 分類, 價錢, 型號 的順序,以逗號隔開,一行一個產品輸入。結果這反而對工程師而言是一個便利的功能,而且整個系統的設定,他可以自己存成一個文字檔備份,也不用做複雜的資料庫處理,或資料匯出轉入的動作。
圖二:商品批次編輯界面
後來我發現,當初本來是寫給安裝工程師用的功能,後來業者自己也無師自通用了起來,他說這比我們另外設計給老人跟小孩用的界面方便多了。
圖三:商品一般編輯界面
其實這個概念也是來自Google,當初看到Google的搜尋界面,給我很大的啟發,比起我們傳統做系統,讓使用者填寫一堆欄位,不如讓使用者任意輸入,我們在用智慧的邏輯去評估使用者要的是什麼,並設法實現。當然我們沒有Google那樣的語意分析實力,不過應用到較小眾的系統上,使用者的特性跟需求固定時,很多判斷是做得到的。
長期使用Google搜尋的人應該會知道,除了隨便打關鍵字以外,Google搜尋也有一些參數可用,只要輸入特定規則的文字,就可以有效地篩選搜尋引擎找到的資料,當然,多數使用者不會去研究這些關鍵字,但他們可能也有精確搜尋的需求,這時候Google就提供進階搜尋,而進階搜尋做的,不過是幫助使用者產生那些搜尋關鍵字。如此一來,同一個界面,並不會限制使用者的用法,隨著系統的發展所增加的服務,也從來不會改變到Google提供的基本搜尋界面。比起做一堆限制,一堆欄位,一堆防呆,我認為Google這個案例提供了一個非常完美的示範,而且都經過了十年,他現在還是那個長相...
對使用者輸入界面進行防呆,往往是最不得已的做法
很多專案管理人員會專注在檢查對使用者輸入的防呆,並且要求界面開發人員從界面上去避免錯誤的輸入。這在工業電腦的觀點是很合理的,因為一個產品一旦完成,他的使用方式基本就固定了,但在使用網路服務的系統架構下,卻是一種困擾,因為隨著服務的成長,對資料的精度要求會有所不同,且網路服務的輸入往往來自多個不同的平台及操作環境,因此如果把保護的機制放在界面上,一旦資料要求的精度放寬,那後面影響到的除錯跟修改的工作就會成為一大惡夢。
舉例來說,之前有金流業者要求我在界面上檢查使用者輸入的聯絡電話必須為十碼才能進行付款,因為台灣地區的手機號碼跟行動電話加起來不超過十碼。但是這個界面只是對應服務的其中一個App,而該服務的前端有至少四隻不同的App,以及來自Web的交易界面。在分別花了幾週的測試之後,各界面都逐一修改到符合標準。但當他們決定要把服務版圖移到大陸或其他國家時,噩夢就開始了。移機的時候,老闆一定認為只是多灌一套系統在另一個國家,頂多把語言改一改,應該一兩個月就可以搞定,但隨著陸續的安裝跟測試開始,這種問題就不斷浮現出來,而且因為分散在各地,所以無法一次發現,只能遇到哪裡改到哪裡,最終的結果就是系統超過預定時間幾倍仍無法上線,就算要上線了,推廣人員也已經對這不定期出錯的系統失去信心了。
根據不同的服務形態,往往要慎選資料的保護方法,例如手機號碼最好的防呆機制,就是發簡訊確認,次佳的防呆機制,就是請使用者輸入兩次。用特定規則去檢查,不適合做在界面,而是應該坐在服務層,讓系統底層在處理資料同時,根據服務的形態去檢查資料,就算日後修改,對前端的個界面影響也最小。
進行防呆之前,是否評估過資料正確的重要性?
延續上個例子,其實刷卡的時候,輸入手機號碼的用意是為了發簡訊確認以及備查,避免盜刷或刷錯金額。但仔細思考就知道這個機制是沒意義的,因為即使我偷用他人的信用卡,只要給定我個人的手機號碼,持卡人也不會收到簡訊,另一方面,刷卡人多半也不一定能在收到簡訊的當下,記得合理的金額是多少(簡訊有時候會延遲送達)。而銀行原本的機制,就已經有措施在避免盜刷或刷錯的情況,因此即使發生錯誤,也仍然可以補救,最重要的是,現場人員原本就應該在第一時間確保資訊正確,才能完全避免糾紛。
如此一來,手機號碼這資訊算是可有可無,即使不做防呆,也不影響系統的主要目的,此時再回去思考當服務擴展時可能發生的困擾以及衍生成本,再加上測試期間拉長延後商品推出時間所造成的損失,其重要性就是可以再評估的。更別說在防呆方面,PM或QC往往對一個系統的幾十個輸入欄位都一視同仁,這帶來的影響不容小覷。
要有正確的認知,錯誤的輸入,得到錯誤的結果,這是非常合理且必要的情況
在不影響系統的主要目的為前提,如果錯誤的輸入,只會影響到該使用者個人,而不影響到其他人的權益,那麼確保錯誤的輸入得到錯誤的結果是必要的。
在開發期間,最常遇到的情況是,錯誤的輸入,就得不到結果,這就是很明顯的BUG,因為不管發生什麼事情,使用者跟系統的互動一定要有個結果。但有的時候,會有人要求錯誤的輸入,也要得到正確的結果,或者錯誤的格式就不能輸入等,這就是相當不理想的做法了。
錯誤的輸入得到對的結果是什麼情況?
電腦是死的,所以很多數據是沒有容錯的空間,但人是活的,所以很多規則都比表面上看到的來得有彈性。我們曾經開發一個考勤系統,功能是記錄員工上下班時間,計算工時,以便發薪水。但是早期的打卡鐘的使用情境,雖然時間是死的,但是判定工時的方式,卻是人在判定的,因此往往有模糊的空間,例如 10:01 分打卡,就當做是 10:00 整到,10:15分打卡,心情好就算他10:00到,心情不好就算他10:30分到,因此大家在時間的認定上,都有一個非明文的容錯空間。但是考勤系統上線後,10:00:00.0000001 上班就算遲到了,也就是說,對電腦而言,遲到一柰秒都不能接受,以至於有人提出說,能不能五分鐘內都不算遲到,但此時一樣會有 10:05.0000001 到底算不算遲到的問題可以爭論。
像這種情況,就是使用者普遍對「對」的定義有容錯空間,因此才會希望系統上也反映出這種容錯空間,但這是因為人類本身就是一個可以不精確運作的系統導致的,電腦在人工智慧發展完備之前,恐怕不容易有那麼大的彈性。
於是,經過研究後,我們把容錯空間又放回人身上。電腦系統不改,遲到一柰秒就是遲到,但是公司制度改為員工必須提前30分鐘來打卡,畢竟打卡設備有限,而員工本來就要在工作時間開始前準備就緒,才能提供完整的服務(當然,正式上班的時段可以往後修正)。如此一來,因為沒有了彈性,所以模糊空間回到了制度面,而新的考勤系統反而又比舊的機制更能確保工作時間,也就達到了系統設計的目的,更甚者,程式沒有為了這個問題作任何的更動。
就如同我們拿鐵鎚敲手指,就會得到腫痛的結果,對工作錯誤的操作會讓使用者本身得到損失,如此一來使用者就必須學著正確的使用工具,這樣才能確保工具的表現,而不是在鐵錘前面加海綿,因為一旦海綿一加,那鐵鎚的產出效率就會大打折扣。
錯誤的資料就不能輸入難道不好嗎?
有關這一點,就要看資料與系統流程的相關性高低,像剛才提到的電話號碼就是一個明確案例。一般而言使用者在系統上輸入的資料有兩類,一種是給程式看的,一種是給人看的(人跟程式都要看得算前者)。凡是會影響系統流程的資料,例如系統需要拿來比對,分析,計算的資料,都是屬於前者,而相對地,只是用來呈現給使用者看的,就是後者了。
給程式看的資料,多半是索引值,系統的設定值,一些執行運算所需的參數等,這類資料錯了,就無法正常使用系統,所以驗證是必要的。而反之有些給使用者看的資料,如會員的姓名電話等個資、留言內容、各種歷史記錄、操作記錄、商品資料、說明或文件等,有很多是存在系統上,方便使用者日後調閱,或是對特定資料的備註或說明,這些資訊的正確性,不影響系統的運算,只影響到建立該資料的使用者,比如他記錯客戶的電話號碼,或地址之類的,這種就無需特別保護驗證。
假如你限制電話或地址的格式,那就影響了系統的使用地區,萬一發生縣市合併這種極端情況,不止資料要改,連系統也要改。而當你限制使用者證件號碼,必須通過台灣地區的身分證號碼檢驗,也同樣限制的系統的使用者只能是台灣人。當你限制使用者資料身上有一堆必填欄位,就限制了建立資料的人務必要清楚該用戶的一切,假如這是個業務系統,有時候業務只有查訪到部分資料,他就不能放進客戶清單管理,而要等到收齊資料,才能建檔。當限制越多,系統發揮的空間越少,因此務必要慎重考慮,只有系統運作必要的資料,需要做強硬的限制。
難道不能有彈性又避免使用者出錯嗎?
如果時間充裕的話當然可以,但只要加個提示就好,例如,現在很多國際型的服務,在建立密碼的時候,會告訴你密碼的強度,但即使密碼強度不足,他也只是在旁邊善意提醒,如果你願意承擔風險,那麼系統也不阻止你建立帳號,反觀近日國內各金融單位,礙於資訊安全法令的限制,紛紛要求使用者要建立高強度的密碼,且必須定期修改,且每次修改不得與之前相同,結果導致使用者不易記住密碼,反而要把密碼寫在便條紙上,或是經常執行「忘記密碼」流程,更增加了暴露個人密碼的風險,完全是本末倒置。這種做法,只是逃避責任,而不是解決問題。
如前面所述,輸入各種非程式用的資料的時候,如果遇到如電話地址這類可能可以驗證的資訊,只要在儲存前做一下提示,如果使用者自己認為自己的資料合理,就仍然讓他輸入,畢竟他如果強硬輸入錯誤的資訊,也只會影響他個人對系統的使用而已,無需要過度保護。
極端的檢查的必要性?
以前我的同學會無聊去測試人家的輸入界面有沒有阻擋全形空白,半形空白,HTML符號,特殊符號,在電話號碼輸入中文字元,在數字欄位輸入全形數字等。認為沒有保護好這些的就是不良的使用者界面設計。在我的觀點看來,如果使用者輸入這些資訊,會影響到其他使用者對系統的操作,那麼我會花時間去排除,如果只會影響他個人,例如他在名字輸入"<"符號會導致他個人資料頁面開不起來之類的問題,我則傾向不處理,或放在最後不得已才處理(例如有新人來要練習寫程式卻沒什麼好寫),而這個做法在小眾的系統服務上,並不會有什麼困難,因為系統是協助他們工作更方便的工具,沒有一個使用者會特意去搞自己,讓自己難做事。
軟體系統都是為了解決使用者的困擾而存在的,好用的軟體,不會讓使用者有太深刻的存在感,而是幫助使用者專注在他要完成的工作上。一個好的使用體驗,就是使用者用了系統,完成了他想做的工作,卻不怎麼感覺到系統的存在。
因為我有個同學很愛反駁我的這個說法,所以我在舉個例子,在你使用了千百次的馬桶之後,你已經不會記得你是為何,以及如何沖水了,你就是流暢的進廁所,滑手機大便,然後離開...