軟體開發沉思錄--ThoughtWorks文集(china-pub首發)(來自軟體界思想領袖們的經驗心得)。看試讀的兩章:第五章充斥著狗屎,第十三章卻瑕不掩瑜。
第五章的一個問題在於討論的大多數問題都是虛的:比如在Java與Ruby的比較中提到的落單方法。這樣的話題根本沒有真理可言,而作者卻毫無顧忌地認為它(沒錯,“它”)的觀點就是對的。但這還不是傷害性的;下面就這個例子說一下狗屎從何而來。
仔細看Java版的isBlank函數,其中對null的判斷,對length的判斷,對每個元素(這裡是字元)是否是某一特殊形態(在這裡是空格)的判斷;實際上isBlank這個函數的邏輯,完全可以看作是某通用邏輯的特化版本,所以這個函數按照這個視角,則不應該出現在String身上(尤其考慮前半部分邏輯)。
雖然他給出的Java版本並未體現某種通用性(這是他自己的問題),這並不成為Ruby版本中那種所謂“一切皆對象”方式“更好”的理由【1】。這類似於someList.length還是len(someList)的爭辯;一個人稍微有一點點泛型經驗或者真正明白什麼叫做抽象(丫的居然好意思在後面講函數式時提到數學),就不會像作者那般輕易下結論。
(要強調的是,本帖不是在繼續到底哪種方式更正確、更“真諦”。如果誰要是認為someList.length就是唯一正確的抽象方式,咱們改天再做探討。)
我在這裡反對的不是物件導向或者任何什麼具體的東西。每一種可以流行很久的方法必然有其特色、適用情境和一套無論幾流的哲學。而且,我也堅決捍衛每個人說話的權利。
但是鑒於某些人對自己公司和自己員工的封裝,我嚴重的鄙視為了自我肯定(實質是一種麻醉)、掙錢(有名才有利)而信口開河的行為。因為他是在裝模作樣的在公眾場合瞎忽悠。一個存疑的討論不應該被當作確切的知識通過某些人的口吻以不恰當的方式灌輸給嗷嗷待哺照單全收的初學者,僅僅因為這些人認為它對。【2】
本身就這章的多語言編程這個話題並沒有什麼對錯;但是,站在自認為可以指導他人的角度,就某一個話題,重複著一些自己根本不真正懂行的話(因為這是自己僅存的“知識”了),並將這些似是而非的觀點廣而告之,這就和排汙器官沒有什麼區別。
讓我們看看這章開頭:其作者在某公司的職位叫做“意見領袖”(再看看china-pub給的這標題,WTF),我看不妨把這個職位叫做“狗屁眼”來的恰當。然後引用了一句某二的徹頭徹尾的胡話“X年之後所有人都用SmallTalk編程無論他們把它叫什麼”云云。這些賣狗皮膏藥的真應該嘗嘗城管的滋味。
第十三章卻做到了腳踏實地、言之有物,並進行了真正有用的討論。在測試的不可避免(這裡不展開討論這個話題)這個前提下,此文在不長的篇幅中全面完整的介紹了一種測試體系,並點到了作者認為讀者應該知道的內容(相比之下第一篇文章卻偏離主旨的狂放屁)。雖然我個人不贊成(某些具體的)測試對正確效能有很大的保障,但仍然學習了很多;另一方面,作者也沒有就“誰更對”這種問題進行宣示。
同樣一個封裝下、同一個公司不同的作者,差異如此之大,那麼在我們的學習過程中,就要注意去蕪存菁了。當一個人、一本書、一套觀點被拿到我們面前時,作為弱勢群體,很容易被很多不相干的字眼加上先入為主的枷鎖,而就我個人這些年犯過的蠢事來看,這些枷鎖擺脫起來卻相對困難。
現在的我是怎麼做的?凡是過分推銷的,都把它們放上了黑名單;那些沒有開發過“真正難”產品的,別想上我的白名單。至於什麼是真正難的這就要靠自己的判斷了。但凡我們睜開眼睛,不要因為生存環境所限一輩子只能寫某種程式,就傾向於肯定同樣寫這種程式但地位比我們高的傢伙,我們就會知道。
注意一個誤區:由於這個地位更高的傢伙和自己從事的是相同領域,於是既然我也是幹這個領域的,那麼他的經驗比另一個其它領域的傢伙更值得參考,即便那個領域需要更高的技巧。這種想法是有害的在於,一個認知水平較低的人在任何領域都更可能採取錯誤的認識;而在一個較容易的領域,由於錯誤的認識危害性不高,可能並未被識別【3】。
在這裡再舉個我自己的例子:Michael Feathers。他是我一個轉折點;對各種封裝出來的技術明星的不滿在他身上爆發了。不但《修改代碼的藝術》【4】讓他榮幸地上了鄙人的黑名單,而且我也意識到建立評價體系的是必須的了;這個社會逼得我們不得不靠自己。
一個方法是在對某人、某書、某方法的第一陣狂熱過後(這有時不可避免,而且在一定程度上增加學習效率)通過強行降溫快速的給出一個真實的評價,並且帶著明顯的懷疑態度去審視它:鑒於學習者在學習目標上的水平,如果不帶有找碴的態度就很難對似是而非的東西免疫。
這溫如何降?真正好的作者會全面、公正的顧及正反兩個方面,但對於很多“大師”我們就必須自己找出那些負面要素。
一個遺憾是,無論尋找負面要素這個具體措施、還是建立評價體系的能力,在不同的人身上確實存在巨大差別【5】;限於我們每個人的具體情況,也很難短時間提高。廣泛(但不見得是大規模)閱讀是一個差強人意【6】的辦法,比如SICP上關於類型系統的一段短短的注釋就協助我對物件導向類型系統建立起自己的看法(並不與SICP相同)起了一個頭。
但值得慶幸的是,通過一次次的求實過程,我們的眼光就會越來越高,眼界也會越來越寬。我相信每個人都可以在職業生涯的前半段提高到適當的水平。
在對自己的評價體系存疑時,白名單就是一個相當重要的拐棍了;就我的經驗,白名單上作者誤導人的時候確實很少。在我剛開始聽說Linus炮轟物件導向時,我已經開始了反思但還不夠;那時的我僅僅持一個保留態度。但自從那以後,我越來越多的體會到了他的言論背後的內容;逐漸,我就學會了如何看待比如現在似乎又有點過氣的DDD之類東西的方法。
有時候做出了一個判斷以後,我們甚至能通過各種各樣的形式得到遠超過這一判斷的好處。
比如,自從我認定Feathers“水平不高”,就順便降低了Bob大叔的評分;甚至有一個更無厘頭的:我降低了Richard Gabriel及其著名作品的評分,就因為讓我不屑的Feathers推薦了此文!當我帶著新的評分(原來的評分是被灌輸的)重新回顧我曾經喜歡的東西,雖然不太可能全盤否定,我仍然找了新的收穫。
這是第一條防線;但這不意味著我們要被反感的情緒或者謹慎所左右:那些真正對的道理,即便從一個“狗屁眼”裡拉出來,我們也應該接受。 只是我們要學著去判斷它們。
注1:即便採用純粹的物件導向觀點,這個作者的思路也不是最佳的:但這在原文中被Ruby的一些細節給掩蓋了。假設使用一個具有Ruby擴充方式的Java而採用他的邏輯劃分,我們就會發現對String的擴充使得應該屬於更基礎類別的共性變成了特性。
注2:營造權威氛圍、單方向發布資訊,這和社區裡有很大區別。社區發布的特點是平等、雙向甚至多向;所以無論作者的視野如何,有益的可能性較大。但這並不是說社區中完全不存在不健康的情況(尤其是對於初學者來說)。
注3:有時候這說明在這些地方過多關注類似的“認識”是沒有太大價值的事情;我的經驗是,在這些地方從業務本身的特性入手可以掌握更多的東西甚至創造更多的價值。另一方面,在某方面認識的局限性很可能就來自於領域是否真的需要這方面認識。
注4:不是說這本書一無是處,但是按我個人觀點,有價值的地方還不如他的偏見和錯誤觀念來得多;這在我過去的文章中似乎提到過一部分。但你不必聽我說什麼,每個人都應該試著自己判斷。
注5:所以我說要建立你自己的評價體系;不要在意比如我這樣的人對某人某事某物的評價。我完全不能排除我是一個菜鳥加2B、且擁有狹隘的偏見的可能性。
注6:之所以這麼說是因為從社區角度來看倡導這個方式未必特別有效:一方面是因為大多數人不願意或者沒條件這麼做;另一方面,閱讀太廣的另一問題是,鑒於資訊劣勢我們有很大機率被不同的噴子洗腦,這就可能造成我們心裡一波一波的長不同品種的草,要結束這種狀況需要很久的時間。