偏好:個人習慣的侷限與反思

經過長時間的工作實踐,我們會逐步養成一些做事的個人喜好或習慣,並且會自我感覺這種個人習慣會是很好的方法。

不可否認,每個人做事情都有些個人習慣,有些特別強烈的,可能其程度還會上升到 “癖” 這個字。明朝散文家張岱在其文《陶庵夢憶》中留有名句:“人無癖不可與交,以其無深情也。”這裏的 “癖” 就是指一個人強烈的個人喜好與習慣。

作爲程序員,過去這麼些年幹得最多的事情自然就是寫程序,關於寫程序也會形成一些個人習慣或者說癖好。自己的習慣或癖好對別人本該是無所謂的,但在團隊合作中,有些時候,我們可能會不自覺地去維護,甚至推廣這種習慣。這種 “不自覺” 的行爲是值得我們警惕和反思的。

習慣形成

工作中的一些習慣是如何悄悄形成的呢?

記得畢業幾年後,我也成了需要帶新畢業學生的 “老” 程序員。其中,帶學生的主要任務之一就是一起做項目,指導他們上手開始寫真正的項目代碼,而不再是實驗性質的課程作業。

我開始工作的頭幾年,可以說是我寫程序最多的幾年,基本也就寫出了我個人的一些習慣和喜好。比如,工程的目錄結構、類的命名模式、接口的參數定義,甚至註釋和簽名的方式,都是我特別在意的地方。每當看到新同學們各自按自己的想象寫得隨心所欲,就感到非常地焦心。

那時候像 Java Maven 這種約定優於配置的工具還沒有流行起來,大家都是按自己的喜好使用 Ant(一種 Java 構建工具)來定義工程項目結構,所以最終導致結構千差萬別。

因而,我就忍不住去把新同學們的工程按我自己的定義喜好進行修改,以一種權威的說辭來強調自己的偏好:“我們要統一下,免得像以前舊項目一樣差異太大,換個項目熟悉起來都要好半天,也不利於相互之間的代碼交流。”

如今回想起來,當時這種 “約定優於配置” 的個人習慣在行業裏還並沒有成爲共識,而我僅僅是出於自己對代碼的 “潔癖” 或者說強迫症,就產生了這種強加於人的衝動行爲。一些年後,Maven 崛起逐步取代了 Ant,這種約定優於配置的方式就變成了 Java 程序員的普遍共識,而我,也可以確認這個習慣基本算是一個好方法,也不再需要去強迫別人了。

以上,就是一個關於編程習慣的形成過程。從中我們可以看出,即使這樣的習慣最後也許真的變成了大家認同的好方法,一開始也不該以個人的方式直接去強加於人。因爲強加於人,總是容易帶來分歧和爭論,最終可能好習慣還沒機會帶來收益,卻因爲分歧爭論直接帶來了損失。

但編程中總結出來的一些方法和原則,很多可能就是始於個人習慣,最後逐漸傳播並演化形成了普遍共識。

共識達成

如今,很多約定俗成的代碼規範,基本就是從早期一些人的習慣中加以提煉總結出來的,然後形成了大家共同認可的好方法,並在組織層面形成了規範。形成了規範的東西,就不再是從個人習慣的角度去強加於人了,而是大家的共識達成。

寫代碼的一些方法能形成規範,但還有一些編程的好方法可能比較難用規範去描述,這些就慢慢形成了所謂的 “編程智慧”,並在程序員之間口口相傳(如今的 “口口” 可能更廣義一些,也包括了互聯網上的文字交流和傳播)。

一些 “編程智慧” 類的好方法,不太好形成具體的規範描述。下面,我就結合我自己的工作經歷和經驗,列舉一些規範建議:

  1. 設計模式。遵守設計模式總是能讓你少踩坑的,但如何靈活地採用合適的模式又是另一種智慧了。
  2. 術語約定。約定了術語,總是能讓口頭的概念和落在代碼上的東西保持一致,減少溝通歧義,從而更高效。
  3. 單元測試。這比任何的代碼評審都來得可靠,哪裏該寫多少測試用例,哪裏可以不寫,這又是智慧了。但不要刻意爲了追求覆蓋率而去寫,覆蓋率的技術統計方法其實是很唬人的,有些覆蓋率很高的項目,該有的 Bug 還是有的。
  4. 隨時重構。對於技術債務,每個月付點“利息”,比好幾年後“連本帶息”去還要感覺輕鬆得多。這條的特殊點在於,這可能是大部分程序員都認可的好方法,但卻不是大部分人的習慣。因爲技術上的債,實在自己還不起,總是可以推脫出去給下個“倒黴的傢伙”,但從長遠角度看,這樣的推脫不會讓你獲得成長,甚至還會阻礙你的發展。

在程序界形成編程共識最經典的例子來自 Unix 的發展歷史,而 Unix 幾十年的發展歷程,不僅僅是一個軟件系統的進化,也是程序設計和編程方式的進化。從它的進化歷程中,形成了獨特的設計原則,而且已廣爲流傳,達成共識。

共識,意味着看待問題共同的思考方式和角度,所有能形成共識的方法都是值得關注的。

分辨反思

編程中除了好方法,還有些確實只是個人習慣的東西,如果我們不去留心區分,很容易模糊了兩者的界限。

舉個例子,我曾經一直有個編程習慣是這樣的。假如有一個查找接口方法叫 lookup(),而實現這個方法內部的邏輯要根據好幾種條件來查找,按不同的參數條件來實現不同的內部邏輯分支,但最後執行時又會走同樣的一段邏輯去存儲裏查找。這樣描述起來比較繞,下面我用個簡圖來說明:

我個人編碼中的方法命名習慣圖例

如上,lookupByXXX 表達了不同參數邏輯的差異化處理,最後的 lookup0 則是一段共享的查找執行代碼。 lookup 是一個公開的接口方法,而後面再加個 0 基本就是我的個人習慣了,表達了內部私有的一種技術性實現,它一定是私有的,不對外暴露的。

這個例子中的編程方法,是讓我對所有類似需要的接口實現模式保持一致。但這確實只是我個人的習慣偏好,我沒辦法並且也不會要求別人也用類似的方式來命名函數和編寫實現,因爲別人也可能有自己的習慣偏好,談不上誰比誰更好,畢竟它並不是廣泛的共識。

那大家都認同並形成共識的方法就一定能形成習慣嗎?也未必,這需要我們去分辨和反思。比如程序員都不愛寫文檔,很多人也沒有這個習慣,但大家幾乎都認同提供規範的設計和接口文檔是個好方法,只是因爲文檔的優先級長期低於完成代碼功能從而被擱置了。

另外,一些流行的概念就一定是好方法嗎?比如,結對編程,是一種流行的概念。它的行爲要求是:兩位程序員坐在同一工作臺前開發軟件。它的優勢作用是:與兩位程序員各自獨立工作相比,結對編程能編寫出質量更高的代碼。其理論基礎是:兩個程序員具有相同的缺點和盲點的可能性很小,所以通過結對編程的時候會獲得一個更好的代碼實現。

但在實際中,結對編程也有它的缺點和劣勢,比如更高的開發成本(畢竟要同時佔用兩個人)。而且,有些人可能從心理上就很不喜歡結對編程的,比如我,因爲坐在一起編程,難免分心而無法進入完美的心流狀態,所以會感覺自己的工作效率都會下降一半以上;並且我也很難接受別人在看代碼討論時,用手戳屏幕指指點點。當然,不僅僅是我,還有更甚者,除了代碼潔癖,還有生活潔癖,根本接受不了任何其他人和自己共用一個鍵盤的。

也許稍微鬆散點,沒有那麼物理上的嚴格結對,而是確保每一個程序員寫的每一行代碼,都能有一個配對的程序員去進行檢視,雖說這個過程完全是異步或遠程的,但效果應該也是可以保障的。這幾乎就是開源項目的協作模式。開源項目的繁榮與成功,也證明了其實踐的協作模式是一種好方法。

總結來說

在你從程序新人成長起來的過程中,要學會區分,哪些確實是值得學習與推廣的好方法,哪些僅僅是自己的個人習慣,特別是在你成長到開始成爲技術管理者之後。

古語有云:“己所不欲,勿施於人。”而己之所欲,若是自己特有的習慣偏好,也就請勿妄施於人了。若確實覺得是個好方法,儘量建議於人,而非強加於人,即使你手上掌握有強加的權力。

反過來看,程序行業,編程實踐中,存在大量流行的概念、模式、原則,甚至哲學,它們的產生都有其歷史背景和過程,並在一定範圍內形成了共識。但你依然需要去對這些流行的共識進行分辨和反思,看看哪些纔是適合你的好方法。若真是好方法,也可以進一步將其培養成自己的習慣。

雖是以編程爲例,但習慣的偏好不限於此。

最後,在你成長的路上,都形成了哪些好習慣呢?歡迎你留言給大家分享下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章