![]() |
VOOZH | about |
全篇文字都是以 Java語 言為背景,如有雷同,絕對巧合。
在你讀到這篇牢騷的時候,無數個項目正在慢慢變爛。
既然標題都用到了」爛」這個詞,那什麼才是爛呢?
在你的項目里,」爛」和」好」一樣無法準確的衡量和定義,在大多數人的職業生涯里,你聽到」爛」項目肯定比聽到」好」項目的情況要多很多。
當你在一個維護型項目面前,一邊嘴裡跑出一萬隻草尼馬,一邊還在上面Coding,最後居然還如期交付了維護任務,你能說那是」爛」項目嗎?
我自己也沒有遇到過真正」爛」到無法維護的項目,因為我就是那個讓項目慢慢變爛的人。
也許,」爛」項目的罪證無法像《如何編寫無法維護的代碼》那樣容易羅列,所以你根本就不認為那是爛。
意識到項目的」爛」與聞到代碼的壞味道一樣是優秀開發人員的基本素養。
不過本文說的」爛」,只是從程式設計師的角度去看項目,與項目本身的創意,項目在公司層面的戰略意義沒有關係。
在我剛出道時(06年左右),那時候的Java生態圈其實已經很強大了,但是我剛畢業工作過的幾家公司,幾乎在項目部署上都沒有使用太多的自動化工具。
有的是直接用開發工具Eclipse打包war文件,其中一家公司,甚至是在本地編譯Java文件,然後上傳class文件到線上伺服器,就算那時已經有ANT這樣的先進工具,可惜我們還是類人猿,沒有進化過來, 要知道 使用製作工具是人類起源的重要標誌.
如今我們在一個最好的時代, Maven成了Java構建的標準,Gradle成了Java構建的新秀, 請把打造高可用自動化工具鏈與開發高可用系統提升到同樣一個高度。
如果你的項目中使用到了工具,但是它卻很脆弱:過多依賴環境,依賴複雜的配置,有時候還會有BUG。
如果你的項目還不能做到一鍵命令構建,打包。
如果你的測試環境和線上環境程序部署時間不在可控範圍。
……
那麼你的項目,肯定會慢慢變爛, 因為效率太低。
是的,從你找工作開始,就肯定聽說了這個詞,如果你在學校的時候就是一個勤奮好學的同志,那麼你早就聽說過了,在Java的世界裡,你不會幾種框架,還好意思出去混嗎,於是很多招聘裡面都提到,精通Spring,Hibernate,Struts,Mybatis … 我入職的一家公司,甚至還有公司框架Demo代碼學習這個環節。
So,當你到公司第一次接觸到項目的時候,我想上面提到的這幾個框架,至少有一個出現在你的項目中,先來看看我遇到的項目中使用框架的情況:
框架一詞原本來自建築學,在軟體行業裡面,本人理解框架,就是解決特殊場景問題的 抽象 實現。本著娛樂的精神,這裡就不引入太書面的文字,容易引起反感。
如果你的項目和我遇到的情況一樣,滿足了上面兩點以上,我相信,只要這個項目還要繼續,就會繼續變爛,原因大概有以下幾點:
如果你學過PMP,那麼上面這些問題可以概括為風險和成本。
引入了框架, 那麼項目成員是否在框架上做足了技術儲備? 如果僅僅是達到使用的地步,那麼由於框架引發的問題,你是否能夠在最短的時間內解決?
不然框架就成了項目的枷鎖,即使不會讓項目慢慢變爛,也不會讓項目慢慢變好。
對啊,沒問題,我們項目裡面的使用Spring,爽得不要不要的,Spring不是提倡面向接口編程嗎,我們有完善的Service接口層。
是的,就像上面提到的,我曾經學習過公司的框架Demo代碼,裡面把Module都分好了,Domain, Dao,Manager(用於管理DAO層的事務),Service,Web。 真實的情況卻是,Service裡面,一個Service接口對應了一個Dao(大部分情況是這樣的),你有幾個數據表,大概就有多少個Service接口,如果有個新業務來了,添加了一張表,就再搞一個Service接口,Service,Dao基本都是在為資料庫CRUD服務。
一個接口類從項目產生就沒有出現過多個實現, 當時定義接口僅僅是為了遵循面向接口編程。
在充滿疑惑的歲月里,我找到了真相,原來我把名詞理解錯了,「DDD」的含義有兩種,一個是Data-Driven Design,一個是Domain-Driven Design
一個沒有領域模型抽象的項目,遲早要慢慢變爛。
框架和模型是讓你站得更高的角度來看項目,最後還是得回到代碼上,好的項目(應該說團隊)一定能夠找到一套規範(當前流行叫」軍規」), 每個團隊制定的規範可能有些不同,但還是能找到很多共性.
經過我多年的經驗,制定規範這事兒,其實重點在如何讓項目成員理解和認同,最後才是執行,很多項目成員對規範的牴觸源自浮淺地認為規範只能讓他們將時間消耗在非功能性需求上.
規範是一種認同感, 但要想讓項目成員建立更好的認同感, 有時候你必須利用人格魅力(如果你有的話),或者慘痛的經驗(老司機肯定有的).
抬頭看看你的項目, 能不能找到一條硬性要求的規範, 如果找不到, 可以直接跳出該文.
如果你有所覺悟,然後只是到網上到處借鑑各種軍規堆砌在項目里, 那麼依然沒什麼卵用.
規範並不能讓你的代碼變得多優秀. 規範只是防止代碼里到處瀰漫著單身屌絲程式設計師(猿)的個人感情色彩,規避一些顯而易見的錯誤.
有了規範, 你有沒有代碼審查?
你在網絡上到處都能搜索到」 XX團隊如何看重代碼審查,XX團隊為了代碼質量開發了一個代碼審查工具」, 可是你很難找到XX團隊是如何做代碼審查的,所以搞清楚如何讓代碼審查起到作用 比代碼審查本身更重要.
總之,在代碼審查之外,你還需要權衡,要不要把代碼審查搞成政治任務,要不要搞成批鬥大會, 如果你在代碼審查的氣氛裡面聞到了壞味道, 那就應該停下來.
一個做好了代碼規範和代碼審查的項目,想變爛都沒那麼容易.
我在大學裡面學編程的時候,似乎老師都沒教過什麼是測試,當時寫TC的時候,老師只是說上機執行,現在回想起來,好像當時的教材也沒有專門講測試。(也許我就沒有好好學過)
從項目代碼來看,最基本的就是單元測試。
你的項目雖然有單元測試,但是他們要麼過時(沒有和被測試代碼一起演化),要麼根本就沒有達到覆蓋率要求。
當你想給一個功能補寫單元測試的時候,發現編寫單元測試的難度比重新實現這個功能的難度還要大,結果你就真那樣做了。
測試的目的就是為了發現儘可能多的缺陷, 儘量 保證質量。
然而很多項目根本就沒有清晰定義出 質量 的邊界,甚至只完成了功能測試。
羅列你項目中的測試項,將他們分類列舉,如果測試項用一張紙都能寫完, 那麼這個項目本身就是爛的,根本不需要慢慢變爛。
再強調一下,如果沒有充分測試(怎樣才是充分測試?)的項目,其實已經爛了。
所有的業務需求你都應該去滿足
業務是項目的基本驅動力,可以說沒有需求就沒有項目存在。
然而對於一個發展中的項目,有可能正是需求在讓它慢慢變爛.
因為我見過太多的需求來至項目控制人員(簡稱領導),而不是來至於真正用戶,這些項目控制人員還會振振有詞地說:」我也是用戶中的一員」,大部分開發人員基本上又都處於食物鏈的最低端, 所以遇到上面這種情況,基本是無解的(排除那些真正執行工程師文化的公司).
大部分項目的需求,都會對應到一個系統功能,系統功能都會有生命周期,但是項目中的代碼卻往往隨需求一起增長,對於過時的功能代碼,沒人敢隨便刪除,然後就變得臃腫。
另外一種情況就是需求超越了領域模型,例如:ATM取款機,讓你植入視頻播放功能(現實生活中卻真有的),你有時候無法分辨出這類需求,然後卻漂亮地實現了它。
恭喜你,你的項目正在面臨慢慢變爛的風險。
負面情緒讓項目慢慢變爛,聽起來有點牽強,其實負面情緒與項目中的」爛」有點像雞與蛋的關係,但這也只是其中一方面,放眼望去,項目中的負面情緒來自於方方面面。
部分開發人員如果遇到《如何編寫無法維護的代碼》 中提到的問題會讓他們大怒,然後抱怨沒有統一的代碼格式化工具,沒有規範的目錄結構,甚至日誌輸出格式也是五花八門……
如果你在項目中經常聽到這種罵街的聲音,那麼你所在的項目還不至於那麼快變爛。
不滿現實,並動手去改變它,這也是優秀程式設計師的基本素養,但你必須停下來思索一下,你周圍的人是不滿的多,還是動手去改變的人多。
我自己就非常願意和不滿現實並且情緒化的開發人員一起工作,非常懼怕那些只是抱怨,說到動手去改變的時候又保持沉默的人。
情緒會傳染,有些情緒在團隊中會產生負面的效果,有些卻能成為動力,這取決於團隊的自我認知能力。
如何識別項目中遇到的負面情緒呢?
放心,如果你在項目中是個領導角色,上面這些抱怨列表你基本上是不會聽到的,如果你只是一個普通的開發人員,那麼就去購買一本《程式設計師自我修養》,將負面情緒轉化為正能量。
有一個老程式設計師自豪地告訴我,他寫的一個程序已經在線上跑了快10年了,從來沒動過。
我只是笑了笑,說了一句:牛逼
如果我寫一個列印Hello world的程序,部署在一台太陽能Linux機器上,然後把它放到外太空,誰知道能運行多久呢。
我做的部分項目裡面,用到的第三方工具距離最新版發布時間有的至少快5年了。
同事告訴我,用著這麼穩定,幹嘛要升級。
你要知道,JDK現在多久發布一次?每次都有哪些BUG修復?有哪些性能提升?你用的這個第三方包,可是在5年前那個版本的JDK下開發完成的,而且那個開發第三方工具包的人有可能還死了。
請注意,我們不是在討論升級的問題,我們是在討論 變化 的問題.
保持現狀是一種惰性思維,它已經麻痹了開發人員對項目變化帶來的風險評估。
如果將項目比做一輛汽車,它只是在不停地行駛,卻沒有定期保養。(重點是你不知道應該保養哪些部件)
不要讓保持現狀的思維腐蝕了項目,讓項目慢慢變爛。
最後記住: