說到重構,其實可能每一個人心中的理解都不太同樣。程序員
單純意義上來講,重構是對代碼的再調整,在不改變業務邏輯的前提下,下降代碼的長度、圈複雜度、重複度,提升其可讀性、可維護性和可擴展性。簡單來講,就是把代碼整的規整乾淨,邏輯清晰,井井有條。數據庫
然而,這每每不是產品線但願獲得的答案,不一樣的產品線在和咱們接觸的初期,都會很明確的說,個人系統須要重構。但當咱們介紹完什麼是重構,若是作重構時,或多或少的,對方會流露出失望或者不覺得然。編程
做爲一個程序員,我固然知道對方在想什麼,把代碼整這麼漂亮有什麼用呢?系統只要沒有bug就好了;咱們沒有這麼多時間花在這種費力不討好的事情上。設計模式
碼神訓練營有一節「編寫可讀代碼的藝術」的培訓課,教如何寫clean code的同時,還有一段專門講重構代碼。聽培訓的同窗多半興趣度不高,然而看起來簡單的規則,其實不是每一個人都真的理解和玩得轉。緩存
產品線關心的是改善他們的業務痛點,因此常常會有人糾正咱們說,大家說的代碼級的重構,咱們說的是架構級的重構。架構
不一樣的產品線的業務痛點可能不盡相同:併發
- 代碼複雜度高,分支多,動輒上千上萬行的代碼,致使問題難以定位,測試覆蓋不到,也不敢輕易修改;
- 相似的bug反覆出現;
- 系統間耦合緊密,單個功能點的修改每每或涉及多處代碼的修改,或者單個功能的延遲致使整個系統沒法上線;
- 系統的CPU佔用率高,Memery佔用率高,要嗎卡死,要嗎直接掛掉;
- 系統響應慢,用戶抱怨多;
- 併發致使的各類不肯定bug,測試環境復現不了,一上線又冒出來;
- 等等;
因此,產品線的指望很是明確,我但願經過架構重構,改善以上狀況,至於代碼漂不漂亮,並不重要。數據庫設計
這種想一步到位,一針見血的想法能不能作到?我想若是是在傳統行業,有了解產品整個成長過程的工程師,代碼通過深思熟慮的設計,仍是有可能作到的。函數式編程
惋惜對於高速發展的互聯網來講,人員流動快,產品上線壓力大,這種任務幾乎就是mission impossible了。函數
不少人想到了,既然原來系統這麼龐大,還沒人熟悉,乾脆重寫得了。問題是誰能保證新寫出的系統能比老系統更好,前人填過的坑,都能在新系統中一一規避呢?
因此,咱們可能仍是須要從代碼重構下手。
咱們團隊有一個說法叫「小步快跑」,其實我還想到一個說法叫「星星之火,能夠燎原」。把代碼的複雜度降下來,重複度降下來,不是最終目的,只是最初手段。
幾乎我碰到的全部重構項目,在重構早期,面對系統已有的問題,接手重構和咱們的同窗有時會哀聲嘆氣,都有種無從下手的感受。然而隨着重構的深刻,對系統的改造開始不僅僅侷限在代碼上,方案也開始逐步清晰。手段和方法開始不斷涌現:
- 採用面向過程編程,仍是面向對象編程,仍是函數式編程?
- 可否引入DSL,代碼生成等方法?
- 是否須要引入設計模式,例如策略,橋或者狀態機?
- 是否須要併發,是否須要同步?
- 是否須要數據緩存,是否須要事件驅動?
- 業務模型是否合理,數據庫設計是否合理?
- 系統分層是否合理,是否作到了單一職責,高內聚,低耦合,可擴展?
- 系統配置是否合理,啓動參數是否合理,線程池是否合理?
- 業務邏輯是否恰當,流程是否清晰?
- 等等
以上這些手法,將再也不被認爲耍花腔,over design,而是重構系統後應運而生的最佳方案。
一個幾十萬行代碼的系統,它龐大,複雜,沒有頭緒,若是盲目的下手,可能會帶來整個系統的崩盤。而重構的做用,就是從一處着眼,把相對獨立的部分重構成如樂高積木塊的一個單元,而後逐步擴散,剝離無用的部分,清理出主線,最終實現一個清晰可擴展的系統。
因此,其實重構能夠說很簡單,也能夠說很複雜。不過有了代碼重構這個鑰匙,再厚重的大門,也是敲得開的。
無論怎樣,要把系統重構或者優化到滿意的狀態,特別是一個已經有幾十萬行的代碼的系統來講,都不是一朝一夕能完成的工做。他須要和開發團隊的總體配合和新需求的共同排期。與其讓系統有一天膨脹到走不動的時候纔想起重構,最好的辦法,仍是把重構融入到平常的工做中。一個好的工程師,或者工程師團隊,應該敏銳的及時意識到系統即將面臨的問題,並及時引入重構。
或許有些你們都認爲合理的事情,實際上是不合理的:
- 你的產品真的須要這麼多代碼嗎?
- 這個系統真的須要這麼多子系統嗎?
- 團隊中真的須要這麼多人嗎?
- 相似的功能真的須要反覆開發嗎?
- 你真的須要每天加班嗎?
經過持續的重構,防止代碼腐化,保證代碼的簡潔高效,讓它適應新的產品需求,或許會是以上問題的一個良方。
最後說一句口號,你不是碼農(屌絲),你是軟件工程師(白富美),你更是意識構建的「藝術家」(高大上)。代碼能夠像一堆雜草,也能夠如變形金剛,好與壞全在你一念之間。當咱們接手一堆爛代碼時,除了罵罵前面挖坑的人,也提醒本身不要成爲下一個被罵的人。