程式設計的精進之法

ThoughtWorks發表於2016-10-28

程式設計,眾所周知被定義為知識工作。所有的知識工作,從業者和門外漢都喜歡把它神祕化,將整個過程以不可知論的風格來解釋。理由往往非常簡單粗暴,無非是“照搬體力工作時代的工作方式會在知識工作中失敗。”

這其實沒什麼靠譜的理論。偶有幾個人能寫寫理論與理由,也跟癔症者的囈語無甚差別。我個人是反對將知識工作神祕化的,我是科學管理原理的忠實粉絲,儘管科學管理原理的具體案例都過時了,但泰勒的研究方法依然是有效的,只是研究者和被研究者發生了一些微妙的變化。

彼得德魯克在《21世紀的管理挑戰》中提到,“知識工作者需要自我管理”,那麼很明顯不是體力工作時代形成的方法不能用在知識工作中,而是不能指望個體之外的人對個體進行簡單的粗暴的分析和命令,不要妄想以此產生很高的生產效率。這個分析和下命令的人必須是知識工作者自己,我們需要自己紀錄自己的行為,然後分析、優化,才能得到生產力的提升,任何向外訴求都會很快的撞上一個“天花板”而無法提升。如果非要尋求外部干預,那麼我們只能說,對於新時代的管理者定位,老闆更像老師,以引導和幫助訓練為主,真正的效率提升主要還是靠自己。

1-floor

那麼書歸正傳,追求知識工作的一種——程式設計的效率,是本文關注的重點。但我們首先要宣告,本文不會給一個可以直接產生高效率的方法,而會給一個可以將生產效率視覺化,並從中發現瓶頸的方式。至少在不改變質量的前提下,可以極大的提升你的效率,如果使用得當,可能會得到質量和效率的雙提升。

本文引入的方法也並不新鮮,簡單說來,就是任務列表法+PDCA的一套組合使用而已。大道至簡,堅持者寡,而堅持下來的人往往都可以獲得數倍的效率提升。

任務列表法

我們做任何事情都應該劃出任務列表,按照列表一項項去完成,這不是什麼特別稀奇的工作方式。然而,很多人的問題在於,列出的問題列表不能達到完全窮盡,各自獨立。

2-todolist

完全窮盡是什麼意思呢?

當我開始做事情的時候,如果不能把所有的事情窮盡,我列出的列表跟我做的事情是不完全等價的,這說明我們的工作行為非常混沌且不可視,哪怕是對自己。

有時,事情看起來在大面上窮盡了,但是做的時候,又會發現新的任務。那說明每一項任務的輸入和輸出沒有想清楚,因此每當發現有所欠缺,就需要輸入新的任務作為補充。於是任務列表就增加了,這也是一種沒有窮盡。

各自獨立是什麼意思呢?

意味著,每一項任務都可以單獨做完,而不需要先做完其中一項任務,才能做另一項。 假如我有三項任務:任務1、任務2、任務3。

我做的時候,必須把任務2做完,任務1才能做完;任務3做完,任務2才能做完。結果我就從任務1開始一路做到任務3,最後再逐步回到任務1,整個過程非常混亂,那就不是各自獨立的。

在現實生活中想做到各項任務都獨立,挑戰還是比較大的,但是在程式設計的世界裡就輕鬆多了。優秀的設計都是要求解耦的,如果做不到,基本等於活兒比較爛。

3-fly

當我們做到“任務的完全窮盡與各自獨立”之後,我們的任務列表法才算達標,這之後才能高效的工作,然而達到這一點並不是一蹴而就的,沒有誰可以一上來就做到任務劃分的完全窮盡、各自獨立,需要不停的刻意練習。所以我們稱之為程式設計的精進之法。

PDCA

PDCA是Plan-Do-Check-Action四個詞的組合。這是著名的戴明環。講究從計劃開始、經過實踐、反思、產生的改進行動再納入下一輪計劃的持續改進過程。

當我們把這一套從工業領域搬過來的時候,我們對計劃的理解還是工業領域那一套。如果用在個人提升方面,我們應該把PDCA微觀化,這之後就有兩個問題需要被解答,一個是Plan是什麼?一個是Check什麼?

第一個問題的答案很顯然,我們前面講的任務列表法就是在形成這個Plan。

第二個問題本身是一個母問題,每當我們對這個問題進行回答,都要回答一個衍生出來的子問題:我們要做點什麼才能在需要Check的時候能夠Check。

常用的套路有兩個:

  • Plan的時候估計一個時間,然後開始做,做的時候計時,做完就要Check這個時間是否達標,無論快了還是慢了(通常是比較明顯的差距才能引起反思,比如20%以上的差距),Check都要反思併產生Action,納入到未來的Plan中去。
  • 估計的任務列表和實際做的任務列表是否是一樣多的?往往是會多出來,這時就要反思,自己在哪裡有不足導致了這個差別。

這些反思往往是發現自己的問題,比如自己不熟悉的知識點、方法,甚至業務知識,最後的Action也往往都是通過刻意練習來提升生產效率,比如反覆練類似題目。有時也會藉助一些工具來提升效率,比如抽取live template,使用快捷鍵,只是效率工具的使用往往也需要刻意練習。有時也可以通過複用技術(其實live template已經是複用技術了)來提升生產效率,然而可複用模式的識別與抽取本身也是需要練習的,否則在那裡糾結浪費的時間更長。

有些同學會感覺到,記錄了時間卻不知道哪裡有問題,這個時候可以跟TDD相結合,把時間劃分為寫測試的時間,寫實現的時間和測試通過的時間。其實除去這幾種時間,還有其他時間消耗,比如調研的時間。不管怎麼劃分,將時間消耗結構化掉,一部分一部分的追求最高效率是一種可行的辦法。

舉例

我們做一個簡單的修改使用者資訊功能的API。那麼我們在某一個Java技術棧上可能的任務列表是長這樣的:

  1. 寫UserController (10分鐘)
  2. 寫UserDAO (15分鐘)

當你真正開始做的時候,會碰到兩種主要的意外:

  1. 任務列表擴張
  2. 時間估計不準

下面就這個例子,就講一講當我們遇到這兩種意外,該怎麼反思和處理。

任務列表擴張

任務列表擴張,顧名思義,就是指我們所估計的任務數量會隨著我們開始工作變的比預想的多,可能有兩種主要原因:

  1. 技術原因
  2. 業務原因

技術原因:

比如在這個案例裡面,第二項任務是“寫UserDAO”,就是一個沒想清楚的事情。我們還需要建資料庫表,我們在一個有migration指令碼支援的技術棧設計上工作,我們還需要寫初始化指令碼和回滾指令碼。也許這是我的第一個表,所以我還得配置資料庫,搞不好還要把ORM的基礎程式碼都寫完,所以這些導致了我可能任務估少了。

再比如,專案規範要求我們Controller不能直接調DAO,要在中間加一個Service,儘管我個人覺得這是一件很二的規範,然而規範就是規範,我對專案技術規範不熟悉,導致我的計劃缺少了一些必要的任務。再比如,我們的專案採用了Jersey,根本沒有Controller這麼一個東西,那麼不瞭解技術框架導致我的任務表從根本上就列錯了。

這種情況屬於我對技術瞭解不足,通過對任務列表擴張的原因進行Check,我會得出一些Action:去了解技術規範、專案的技術架構、現有的程式碼,以防止以後的任務畫錯。

業務原因:

也比如在這個例子裡,在更新使用者的API裡不能更新密碼,所以我們還需要一個專門修改密碼的API。再比如,這是一個遺留系統,使用者資訊的修改會觸發資料庫裡的一系列觸發器,進而修改系統的其他資料,然而有些修改是有前提的,那麼我就需要更多的任務去處理這些前提條件;或者當資料變化時,要求我去修改系統裡的其他資料,那麼我就需要更多的任務去完成這些工作。

這種情況屬於我對整個系統的業務瞭解不足,通過對任務列表擴張原因的Check,我會得出一些Action:通讀資料庫表、通讀程式碼、更全面的閱讀需求,或者跟需求方更多的溝通,以瞭解業務。

時間估計不準

時間估計不準就簡單很多,在這個例子裡,可能的主要原因也有三個:

  1. 任務列表擴張了,但是我沒意識到。比如UserDAO寫起來沒有我想的那麼簡單,所以多花了時間;
  2. 單純的技術不熟練;
  3. 花了太多時間在糾結上;

對於隱藏的任務列表擴張,不準確的時間估計給了我們一個很好的線索去發現。一旦發現了,可以如前文所述去處理,也就不再贅述。

4-time

對於單純的技術不熟練,正如前文所述,要設計刻意練習。比如我就曾設計過針對資料庫的增刪改查訓練以提升自己的速度,使我即便使用TDD依然保持一個極高的速度。我們或許不曾意識到,基礎能力的薄弱對於我們的高階能力的限制有多嚴重,這種體驗也只有基礎能力已經熟練的人去教基礎能力不熟練的人一些高階技能的時候才會發現。這種視而不見的收益,使得大多數人都會輕視基本功的練習。哪怕已經獲得收益的人,也容易鼓吹要更多的啟發而忽略了基本功的價值。

對於花了太多時間在糾結上,這其實也是一種不熟練,是對設計知識和能力的不熟練。之前看的設計知識只能有一個大概的感覺,對於每個知識的邊界、使用之後的發展、如何從一種設計過渡為另一種設計瞭解不清,從而害怕在那一刻犯錯。實際上真正值得糾結的部分沒有那麼多,大多是自己嚇自己,或者引入了過度設計。

當然也有一種情況是暴露出了架構級的問題,比如我們對於應該提出的原則性規範沒有提出,導致我們每個地方都要現想,大家可以想象在沒有RESTful之前設計Web API,我們可能真的是每一個API都現想的,有了它之後,我們的糾結時間就變少了。這種情況下,通過本方法,架構師也算是有了相應的資料支援,那麼架構師也就有了發現問題的一種工具。

結論

總的來說,任務列表法+PDCA式工作法形成的組合方法,是一個通過逐漸提升個人能力以實現高效工作的方法。這兩種方法單獨拿出來用,都會由於各自的侷限而觸碰到各自的天花板,只有有機結合才能真正突破這個天花板。

剛開始使用時,很多人會感覺到一些痛苦,這一點上我只能說,提升就是痛苦的,而新的習慣一旦養成,痛苦也就不翼而飛,所以美國心理學之父威廉詹姆士說,“我們需要在儘可能早的時候,讓儘可能多的有用動作變成自動的和習慣的……一段痛苦的艱難時期之後就是自由的時光”。當我們的基礎能力達到一個極高的水平之後,會發現爭取自由的籌碼會變得更多。

相關文章