先分享三個有點滑稽的事情。app
有一天我去飯館吃飯。點單後我就在座位上等着上菜了。等着等着,忽然服務員跑過來講:「對不起,咱們的西紅柿剛剛賣光了。麻煩你去一趟西門菜市場,買倆西紅柿回來,咱們才能給你作菜。」ide
有一天我去飯館吃飯。點單後我就在座位上等着上菜了。等着等着,忽然服務員跑過來講:「對不起,咱們廚師想請你試吃一下他創新的新菜。不過他本身還沒嘗試過,萬一吃出事兒來你得本身兜着哦。」性能
有一天我去飯館吃飯。頭一天去吃的時候,一切如常。次日我又去,點了和第一次同樣的菜。沒想到,服務員忽然向我扔來一個盤子,把我頭都砸破了。測試
現實中固然沒有這樣的飯館。哪家飯館敢推出這樣的「服務」,分分鐘被掀桌子砸場子。然而咱們的系統中,卻真真切切的存在有這樣的「服務」。優化
咱們系統對接過一個服務。有一次,這個服務的內部數據要作遷移,從一套文件存儲系統遷移到另外一套文件系統中。這個服務的負責人向服務調用方提出的方案是:他們提供一個新的查詢接口。服務調用方若是先調用老的接口查一次?若是查不到數據,再調用新的接口重查一次。這跟廚房沒有西紅柿了、要顧客本身去買回來,不是同樣的麼?spa
使用這種「顧客本身去買西紅柿」的方案,直接後果就是本來只須要在服務接口內修改一次代碼就能夠解決問題,最後卻須要調用方作了個全面的篩查、修改了八九處代碼才完成。若是後續還要再有進一步的修改(例如將文件所有遷移到新的文件系統上、從而讓老的文件系統完全下線),還須要調用方再作一次全面篩查、再修改若干處代碼才能完成。code
把服務內部的實現細節「擴散」到服務外部,這就是所謂的「低內聚」。不少服務——不只是跨系統服務,還有系統內部經過interface來提供的服務——都有這樣的問題。有的Excel解析服務要求調用方傳入JXL組件中聲明的類。這樣一來,它就把內部的實現細節擴散到了調用方,從而使得調用方和解析服務本身都被綁定在了JXL組件上。結果,這個Excel解析服務就沒法「順滑」地切換到POI,也很難升級到Office 2007及之後的版本了。orm
另一個系統提供的「服務」更使人哭笑不得。有一天那個服務的負責人忽然找到我,說大家調咱們的接口時加幾個參數吧!我有點奇怪的反問他,沒有接到新需求上線的通知,爲何要加參數?他回答說,他們作了一些優化和改進,可是測試測不過來,因此想讓咱們直接在線上幫他們測一下。我當時差點沒背過氣去:這廚師一口都沒吃過的新菜,就敢端上來給顧客吃?鹹了淡了仍是小事,萬一食物中毒把顧客吃死了,這責任誰擔?blog
上面那倆「服務」好歹最後還沒出錯。還有一個服務提供的查詢接口直接引起了線上問題:這個服務接口竟然不冪等。第一次查詢時,接口還能正常返回數據;一樣的數據再次調用時,接口竟然給返回了一個異常。這不就是那個第二次點一樣的菜就拿盤子扔個人服務員嗎?接口
在沒有其它操做的狀況下,用一樣的數據調用一樣的接口,返回一樣的結果,這就是冪等性。默認操做下,查詢接口都應該是冪等的。我是真想不通這個查詢操做是如何作到不冪等的——要讓它不冪等,比讓它保持冪等還更費精力。
爲何會有這樣的服務呢?由於這些系統提供的「服務」並非面向它的用戶、而是面向他們本身的:本身省心省力就萬事大吉了,用戶?管他呢!由於沒有人去掀桌子砸場子,因此這樣的劣幣能夠繼續流通、甚至驅逐良幣。
咱們要作怎樣的服務呢?具體的要求——冪等,健壯,穩定,隔離,高內聚低耦合,最大努力,高性能,等等——就不一一說了。至少在態度上,要把本身當開飯館兒的,把用戶當作顧客:別讓顧客來吃個飯還滿肚子牢騷。能力差、態度好還能培養;能力好、態度差真是難以引導,在IT這個技術突飛猛進的行業裏,很容易就滑入能力差態度差的垃圾堆裏去了。