最近有人找我討論專案中日誌功能的整合問題,他認為以 log4j 實作的 Logger 已經完成了,所以系統後端的 service 實作應該直接呼叫到這個特定實作。
不對吧!依據我們系統的架構,任何的實作不應該相依到其它的實作,而是讓有 log 需求的 service 實作擁有一個標準的 Logger 界面,不管以什麼方法實作你的 Logger,只要實作這個標準的界面就可以不讓 service 實作被另一個實作來綁住,這是我們的鬆綁策略,一直以來我們就是這樣做的呀!原來用 console 的 SystemOut 實作,而現在只要把那個實作抽換掉,因為我們用 springframework 來做反轉控制,所以連 Factory 程式都不用寫,只要設定 context 把 Logger 的 bean 應對的 class 換掉就搞定了。
可是對方似乎很堅持,認為用注入的方式太複雜了,他想要用靜態連接,只要用一行程式就好了,不用設什麼設定檔,也不用宣告 attribute 及實作 setter 及 getter。
我發現再這樣討論下去,問題好像會失焦喲,於是問道:請問現行設計有什麼需求不能滿足嗎?對方回應:可以滿足,但這樣作很複雜,程式不好寫,因為…。其實我不想聽他解釋,為什麼?因為既然需求可以滿足,就沒有必要改變我們的設計,他想要做的事是以特定實作來主導設計,而不是面對問題來調整設計,既然要用這種頭痛醫頭,腳痛醫腳的做法,那就不需要架構的藍圖了,而可憐的對方他其實是NPS(No-Problem Syndrome)-沒有問題症候群(Gerald M. Weinberg,1986)的患者,而且似乎病得不輕。
面對沒有問題症候群,我只能說:您想做就去做吧!出了問題不要來找我,我不想討論對設計主觀好惡認定的問題,無端更動可滿足需求的設計的後果請您自行負責。
這件事情其實透露著我們對問題管理的態度問題-我們是不是該針對問題來規劃與控制,很多程式設計師喜歡想到那裡寫到那裡,然而當問題規模的複雜度已演變到您所無法掌握時,這種變化無常的做法會為軟體開發過程中帶來許多的意外,所以我們必須要針對我們想解決的問題來計劃,並且依照問題演變來控制使事情的結果趨進我們的預期。如果我們找不到問題,卻有解決方案產生,很有可能我們正在以技術來主導需求,然而沒有找到正確的問題,做的事情只是徒然浪費時間罷了,這跟溺水的人胡亂掙扎卻愈弄愈糟的情況有何兩樣呢?
姑且不論設計要不要與實作分開,也不要討論相依注入是不是好方法。針對真實問題來設計,在軟體開發的實際作法就是針對問題來設計界面,然後依界面來找尋適當的技術解決方案來實現。界面是一種規格,依據規格來實現技術方案,這樣才能使設計與實作達到均衡,而不會使軟體開發太抽象而無用或太僵化而無當,同時關注軟體開發的虛實之道。
先決定我們要什麼再去想我們有什麼吧,千萬不要用我們有什麼而遺忘我們要什麼。Logger 的實作未實現先前所設計的規格,聰明的看倌您看到了該怎麼辦了嗎?問題不在於設計規格不適用,所以更改設計規格是沒有用的,問題是出在開發團隊沒有溝通好,既然如此,挖東牆補西牆然後以求削足適履的做法,根本就沒有解決問題。想想專案變更管制的三大原則,沒有面對問題,做事情怎麼會有效果呢?
自動引用通知: 把抽象化當技術的繆誤 « 同人的生活派對