也談TDD,以及三層架構、設計模式、ORM……:沒有免費的午餐

自由飛發表於2017-07-06

想在園子裡寫點東西已經很久了,但一直沒有落筆,忙著做 一起幫 的開發直播,還有些軟文做推廣,還要做奶爸帶孩子,還要……好吧,我承認,真正的原因是:

太特麼的難寫了

 

但再難寫也要寫啊,要等到“能寫好了再寫”,怕是黃花菜都涼了——尤其是技術類文章,時效性非常強的。

剛好罈子裡這篇部落格:關於拒絕測試驅動開發(NoTDD),看評論爭議不小,而這個問題也是我最想寫的,所以,蹭個熱點,呵呵。

 

其實我很好奇,部落格下面熱烈討論的童鞋,有多少人是真正的在專案中堅持過TDD的。

我公司裡的專案,從來沒有哪一個專案是要求TDD、能夠TDD的;我自己的專案,堅持過TDD一段時間,而且應該是非常久的一段時間,尤其是Entity部分,但現在我基本上都已經放棄了。

為什麼呢?

可以洋洋灑灑千言萬語,也可以簡簡單單三個字:不划算

 

其實不僅僅是TDD,還包括三層架構、設計模式、ORM等等這些東西,存在大量的爭論,莫衷一是:說它好的把它捧到了天上去,說它不行的批得它體無完膚,雙方都有大牛為其站臺,都可以一二三四五的列出長長的清單,而且每一條都很有道理……

當討論變成了一種辯論,當辯論變成了一種罵戰,最後拼的就是誰的態度更堅決,誰的言辭更犀利,誰的聲音更大……所以雙方的觀點更加的偏激、對立,而這其實無助於我們客觀冷靜的來分析問題。

 

說理太枯燥了點,還是聽飛哥講故事吧,呵呵。

 

最早,我剛接觸“設計模式”。什麼玩意兒啊?!整本書,就一個感覺,“脫了褲子放屁”。明明一個物件,new一下不就OK了麼?什麼Factory啊Builder啊,搞毛線呢?所以一直是雲裡霧裡的,包括那些開閉原則、依賴倒置,都似懂非懂的,沒幫上我什麼忙。

直到有一天,也不知是在哪裡,我看到了三個字“上下文”,或者說一句話,大意是:只有理解了上下文,理解了設計模式想要解決的“問題”,你才能真正的理解設計模式。不知道是不是那時候積累也差不多了,茅塞頓開恍然大悟!

我在架構之路(一):目標裡說過:設計模式是藥,看評論其實很多同學沒有理解,對照這句話看能不能明白過來:理解了設計模式想要解決的“問題”……?要解決的問題就是“病”,沒病就不要亂吃藥;同理,沒有“問題”,你也不要亂用設計模式。

 

一通百通。

所以從最基礎的物件導向、到三層架構、ORM、以及敏捷開發、TDD……,所有這些概念方法,本質上都是要解決問題的,而且基本上也是能夠解決問題的。

而你,認為它“沒用”,其實最大的原因是:你還沒碰到這方面的問題

在這裡,大家一定要區分兩個概念:“它解決不了問題”和“它(對我)沒用”。還是用藥做比喻,“這藥治不了病”,和“這藥(對我)沒用”是兩個概念。而且尤其要注意的是這兩個字:對我

換到專案中,就是這種架構這種開發模式,適不適合這個專案,能不能解決這個專案開發中遇到的問題。

其實之前我也看到過類似的提法,比如:xxx適合“大”專案。但用“大”和“小”來區分專案,毛糙了一些,很多時候,並不見得正確。最正確的做法是:你瞭解專案的特點,同時也瞭解各種模式的優劣,從而能夠正確的匹配和選擇。當然,這是一個非常龐大的話題,這裡沒辦法展開了。

 

好,上面我們提到了“優劣”,所謂優勢和劣勢,但其實,這個提法並不準確。優勢,大家都可以承認,解決了問題嘛;但劣勢……什麼叫做劣勢?不服……

我更願意用另一個詞:成本。

“天下沒有免費的午餐”。

這是一個經濟學上的諺語。一提到這話,我就想起我大學的時候坐在教室裡聽老師講《西方經濟學》……往事歷歷在目,誰曾想,我會是今天這個樣子?

再說點題外話吧。

【野生程式設計師】:優先招聘是意氣之作,但並非完全意氣用事,在我該不該轉行?(一)野生程式設計師的優勢一文裡,我就較為詳細的闡述了野生程式設計師的優勢。簡單的說:做架構,做專案管理,需要一個更巨集大的視野,而不僅僅是二進位制和計算機原理。

這裡,我們還是回過頭來看,什麼叫做“天下沒有免費的午餐”?不要理解為“做人不要貪心以免上當”之類的喲!你可以理解為:做任何事情都需要成本。但我更喜歡另一種說法:凡是選擇,必有代價

 

具體到專案中,不管(注意是不管,無論,隨便……)你選擇是不是遵循TDD的規範要求,只要你選擇了,就必然有代價:

  • 不使用TDD,就會在程式碼的重構、維護、健壯性等方面付出代價;
  • 使用TDD,就會在測試程式碼的開發和維護上付出額外的代價。

無論你怎麼選,一定是要付出“代價”的。換言之,程式碼的“低耦合”“可測試”“便於重構”……不可能從天上掉下來,一定是有成本的!

 

這本來是一個最簡單不過的道理。

然而,當我們迫切的想達到一種目標——尤其是這種目標是美妙的、神聖的、寄託了我們某種強烈情感的時候,我們常常會忘記達成這個目標的成本。

就個人而言,就是通宵達旦廢寢忘食樂此不疲,這是你自個兒的事;但對於團隊,對於專案呢?“不計一切代價”就是一種蠻幹就是瞎搞,後果往往是災難性……

另一個很有意思的現象:我們的輿論,我們的文化,是鼓勵“不惜一切代價”是鼓勵“克服重重困難”的,這會讓我們有一種莫名的衝動、一種熱血沸騰的快感。理智和感性天然就是不相容的?

 

那麼,我是反對TDD的?

如果你心裡還有這樣的想法,說明你還是沒弄明白我在說什麼。

無所謂支援和反對,沒有這樣簡單化的答案。

事實上,你需要的,是做一個成本和收益的分析:針對特定的、具體的專案!

 

沒有一個放之四海而皆準的準則。

不同的專案,有不同的要求,應該因地制宜的採取相應的策略。

 

這樣談下去還是會很空,我以 一起幫 為例。

我為什麼要放棄TDD?因為我對這個專案沒有太大的信心,我目前最需要的,是儘快的把專案的原型拿出來,放到市場上進行檢驗:大家喜不喜歡,有沒有前景,收集正面的反面的意見反饋……如果大致符合預期,我就繼續做下去;否則,就要快速的進行調整。而我現在的人手又非常有限,好吧,其實就我一個人,所有的程式碼都得我一個人寫;好在網站出bug問題不是很大,所有的使用者都是種子使用者,他們可以直接的給我反饋而不會因為一兩個bug離我而去……

所以綜合上面種種考慮,我並不需要TDD,至少暫時不需要。也就是說,程式碼質量差一點就差一點,可以忍受。如果專案擊中了使用者的痛點,我可以以後花更大的代價來“補”;如果專案針對的是一個“偽需求”,我就應該儘快止損。

你看,並不是TDD不好,並不是TDD沒用,而是我現在“用不著”——這才是三觀最“正”的,最無懈可擊的理由。·

順便說一下,我現在採取的策略,我把它稱之為“懶人策略”:一開始不寫unit test,但一旦出現bug,fix bug之前,首先寫unit test,然後在fix。(慚愧啊,仔細想想,這一點我都沒完全做到,(⊙﹏⊙)b)

 

其實我覺得呀,當然僅僅是“覺得”了,大多數的“大牛”們,其實是明白這一點的——雖然他們從沒有像我這樣系統明確的表述出來。

我這樣推斷的原因是:現實中確實沒有太多TDD實踐的專案。

實踐TDD的機會其實是非常渺茫的,就我目前能想到的:

  1. 開發團隊,尤其是架構師必須有相當的水平。我在架構之路(三) 單元測試就講過:單元測試不是那麼好寫的!凡是可(易於)測試的程式碼,一定是“低耦合”的,模組之間是具有相當大的“獨立性”的,不然相互牽連,將非常難以測試。而隨著業務邏輯的耦合度(複雜度)越來越高,解耦的難度也就越來越高。反正據我的觀察,一般的開發團隊根本hold不住。有時候想想,非常之詭異:耦合度不高的專案,其實又沒有多大的必要做TDD?
  2. 專案負責人對專案能夠長期存活具有強大的信心。TDD的實踐,是前期投資,後期收穫。相當長一段時間,你都會覺得寫單元測試非常無聊,只有到了後期,業務邏輯越來越複雜,到處都是千絲萬縷的聯絡,牽一髮而動全身,經常一改動單元測試就跑不過的時候,你才會覺得“咦?這玩意還真的有用呢!”但是,注意這個但是,專案負責人有沒有足夠的信心:這個專案能撐到那個時候?!市場朝秦暮楚變化無常,幾乎所有人都是走一步看一步,摸著石頭過河,哪裡能顧得那麼長遠?
  3. 專案從一開始就不趕工期,允許使用大量(至少是雙倍)的時間來寫單元測試。就算是我有信心這個專案沒問題,但時間允許不允許?商場上爭的就是一個先手,快魚吃慢魚,要快,要搶先佔領陣地。這就和強行軍一樣,確實有很多問題,不如步步為營穩妥,沒有重武器,會有掉隊減員,部隊非常虛弱……但只要先到達陣地,其他一切都在所不惜。

所以,我非常好奇,究竟有多少童鞋真正參與過一個嚴格按TDD模式實施專案?

 

那麼,TDD是不是就不值得學習了呢?

當然不是的!

 

+++++++++++++++++++++

 

真的頂不住了!

12點了,超級 =_=

展開寫還有很長很長,強寫腦力也跟不上了。先這樣吧,有時間我們下次再聊,晚安,各位。

 

呵呵,偶然中發現的,小小的一個成就,紀念一下。

 

相關文章