關于軟件開發的一些牢騷

寫在前面

我要寫得都是一些牢騷滿腹的東西。包含了我十年來覺得很不爽的東西,也有一些我覺得很不錯的觀點。寫代碼是個辛苦活,維護代碼更辛苦。有些時候為了趕時間會寫出低質量的代碼,然后花大量的時間去還債。但是有些時候低質量的代碼并不是由于時間的原因造成的。

客觀來講,低質量的代碼可能是由于程序員對需求的了解不夠深入而引起的。大部分的軟件都是應用于各行各業的,而程序員大部分又都是CS專業畢業的。拿醫療行業舉個例子,寫代碼的人和最終的使用者之間的差距,用“鴻溝”來形容都不為過。而且這種“鴻溝”基本上沒有彌補的可能性。程序員改了無數的BUG,可能都不知道軟件是在什么樣的環境中被什么樣的人所使用的。在沒有充分了解需求的情況下寫出高質量代碼的可能性是有的——這需要一個能力非常強,而且對于行業知識非常了解的人來帶領整個團隊——,但是這種可能性很低。

主觀來講,在這個世界上壓根就沒有太多所謂的高質量代碼。高質量代碼的分布能遵循2/8原則就謝天謝地了。首先“高質量”這三個字的含義都很模糊——對于不同的行業,不同的時期,“高質量”所指代的內涵,以及內涵的優先級都是不一樣的。舉個例子,20世紀80年代的代碼,大約是以運行速度快和占用內存小為“高質量”的標桿的。而到了本世紀,硬件資源不那么稀缺了,在大部分的場景下,可讀性和可維護性要優先于運行速度和空間耗費。即便對于同一個系統,在不同的模塊間,代碼的要求也可能是不同的。對于DSP里運行的代碼,首要因素是速度快和結構清晰,而上位機的代碼可讀性更重要。

啰嗦這么多只想說,寫好代碼是一件千難萬難的事情,是一個需要隨著時間而累積和修行的事情。只有扎實地做好每一步,才能寫出“高質量”的代碼。

基本原則

十年開發,大部分都是在修修補補,根本沒有機會打造屬于自己的開發環境和開發模式。幾個月前從公司跳了出來,算是開始了一段創業歷程。這是我有生以來的第一次。以前我對創業是不屑的,因為在我的觀念里,好的技術全在大公司里,所以我前三年全部的經歷都在琢磨如何提升自己,如何進入大公司。在大公司里待了七年,修修補補,挖坑排雷。這七年的提升不僅僅是技術上的提升,更重要的是心智和領導力的提升。當你的思維進入了正軌,大部分技術都只是時間而已。當你見識得夠多,所有的眼花瞭亂其實都是萬變不離其蹤。我不能說所有的東西都是一樣的,但是解決問題的思路也就是那么有限的幾種。以前沒有實現,并不是前人不夠聰明,而是現實世界的約束太強——巧婦難為無米之炊。因此,作為開發者,最理智的作法是從現有的技術里面,挑出我認為最好的東西(有時候是隨機碰到的),組合使用它們,實現我的系統。

舉個簡單的例子,我選擇在開發中用Conan進行二進制包管理。其實這種類型的包管理工具一直都在我們身邊——Nuget就是一個很成熟的應用。但是我為什么不選擇用Nuget呢?沒有什么特別的理由。我之前對于Nuget的使用體驗并不是特別好,無論是上傳還是下載都很費勁。正好在推上看到了Conan的宣傳,就下載來用用,發現不費勁,我要的功能它都提供了,所以就開始用起了Conan。

這樣的選型方式在我前七年的工作環境里確實有些隨意。大公司對于正式引入開發流程的任何工具和設備,都有嚴格的驗證流程需要遵守。并且要做出若干的表格進行對比分析。這樣做有它的好處,但是對于創業公司未免就有點“殺雞焉用牛刀”的感覺。并且隨著整個業界水平的提升,同一種類型的工具在質量上并不會有太大的差別。這也就是我敢于隨心選型的心理基礎。

總結一下我的基本原則只有兩點:

  • 適用于小型團隊
  • 看眼緣

開發語言的選擇

十年之間斷斷續續接觸了很多編程語言:C++, C#, Go, JS, Scalar,等。其中C++是我吃飯的家伙,所以格外花得時間多一點。其它都是有需要的時候翻翻文檔,邊查邊寫。幸運的是,除了C++之外其它語言學起來都不是那么難。C++活了這么多年,都快成活化石了,雖然大家都覺得它很難搞,但是總還是有它的強項。

首先就是性能問題。我們所開發的系統是一個封閉的系統,要給客提供軟件、硬件以及機械結構的一整套東西。并且,封閉式的系統一般情況下不會升級硬件,網絡資源也很有限。因此,相較于開放式的開發環境(類似于網頁應用或者一些桌面應用),封閉系統的計算資源受到很大的制約,性能就成了一個非常重要的考量方面。

其次與已有的成熟系統有關。感謝開源社區的發展,以及全世界無數英才的無私貢獻,現在已經很少需要從無到有地開發一個項目了。大部分基礎性的工作在社區里都能找到。作為開發者所要做的事情,就是找到你需要的項目,再把這些項目做裁剪,改進并膠合起來。除了開源社區,你也總能找到一些商用軟件可以全部或者部分得解決你的問題。這些開源或者商業的軟件所使用的語言,一定程度上會決定項目的開發語言選擇。

這些原因綜合起來,讓我決定以C++作為主力的開發語言。

單元測試

十年C++的開發經驗中,寫單元測試的經歷少之又少,也只在我自己的業務項目里面會寫寫測試用例。在公司正式的開發過程中,從來沒有寫過單元測試。因為大家都很明白,給C++寫單元測試就是一個坑,尤其是給一個已經跑了20年,并且從來沒有重構過的系統寫單元測試,這個坑不是一般得大。對于這種老系統,寫單元測試的可能性已經幾乎為零(需要重構幾乎所有的業務代碼才有可能寫出較大覆蓋率的測試用例),更不要說市場部門還在不停地壓縮開發時間。另外,這種老系統還有一個特點就是所有的開發人員被迫使用“open-close”原則。對于這種老系統已經沒有人能夠完全理解(比深度學習訓練出來的網絡還要神秘),所以最保險的方式就是加代碼。有些年輕人就是不信邪,但是碰過兩次壁之后就都學乖了,十年來從沒有過例外。

所以在系統開發的起初就要求必須給每個組件寫單元測試和系統測試。單元測試是對源代碼的測試,而系統測試是對組件的測試(系統測試可以是對單個組件的測試,也可能是對多個組件組合功能的測試)。在C++里組件一般是以shared library的形式出現,也有可能是header only library。無論是哪種形式,原則上每一個體現具體功能的文件都應該被測試到,即單元測試應該直接將相關文件包含進來,針對里面的代碼寫測試用例,而不是針對組件暴露的接口寫測試(這屬于系統測試)。比如有一個名字叫Foo的庫,庫里面有4個文件分別是FooA.h/cppFooB.h/cpp。在做單元測試的時候首先需要建立測試工程TestFoo,然后將Foo里的4個文件全部加到TestFoo工程里,然后分別針對4個文件里的代碼寫測試用例。然而實際上這樣的測試用例很難寫(有時候基本不可能,有時候則是代價太大)。前段時候用Boost.Asio寫了串口通信的庫,跟串口相關的功能就很難寫測試。另外googletest(我在項目里使用google test)也沒有很好地支持異步調用。

對于沒有反射支持的語言,單元測試都會是個頭疼的問題。很多測試代碼寫起來非常繁瑣,我甚至一度懷疑寫單元測試是不是一個正確的選擇。尤其是在寫Fake Object的時候,想要模擬一些與硬件異步通信相關的行為,經常會被搞得焦頭爛額。但是一但單元測試寫出來了,這些測試用例就會跟著你的項目一起成長。在寫單元測試的過程當中你會更加了解你自己的代碼,也更了解項目的需求,扎扎實實地寫出高質量的代碼。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容