什么是重構?
- 重構是在不改變軟件可觀察行為的前提下改善其內部結構。---Martin Fowler
- 通俗說法:看起來沒做啥調整,讓系統繼續更好的滿足客戶需求。同時,希望重構完成后,這個系統能夠多蹦躂幾年。
重構的分類:
- 代碼重構
如果想了解代碼方面的重構主要有哪些方法,可以參考《重構:改善既有代碼的設計》、《重構與模式》。
之前我們在有次討論的時候,一個童鞋說:“我們現在的程序設計都被框架封裝了,設計模式基本是用不到的。”這個說法我不太同意。因為我們現在也在進行代碼重構,拋去設計不談,但從代碼風格上,最令人吐槽的是里面充斥着大量的if和else。剛畢業的童鞋可以覺得很正常。但是稍有經驗的人就知道這些邏輯計算應該用策略來代替。設計模式是從細節代碼到設計架構處處充斥着的一門設計美學,任何工程師都需要掌握和學以致用。
- 架構重構
如果想了解架構方面的重構主要有哪些方法,可以參考《軟件設計重構》。下面列了一些架構重構方面的主要考慮點,並對其中一點做了說明。
1>可擴展和負載均衡策略
2>數據庫的讀寫分離和主從切換
3>按需擴容
4>兩地三中心,機房故障也能穩定的提供服務
5>持續的容量規划
每個階段都有自己的業務目標。訂單量會對系統容量有新的要求。針對業務目標做評估,對組件做評估,看當前支撐的量是多少,找到其中的瓶頸點做架構升級。應該有1.5倍到兩倍的冗余。把握節奏,太早會影響需求的迭代速度,運維成本高。太晚會不足以支持單量。
技術方案長期規划,逐步實施。持續重構,重構在每個階段都要有人力。
6>持續的性能優化
7>性能影響用戶的留存率、成本
8>單機容量低、響應慢
重構的目標:
- 最終目標:更好的承載業務
- 具體目標有:改進設計、模型規范、重建生命周期、增大負載能力、提高響應速度、抽象、解耦、無法維護、擴容、業務復雜度、降級開發成本、容易理解、技術棧革新
重構面臨的問題:
- 新的系統就不會再有問題了么?
- 再過幾年,新系統也會變成老系統
- 一個正在運行的系統,如何新老系統平滑遷移?
- 日常需求不停頓,還要花費大量精力重新設計編碼
- 之前踩過的坑如果沒有很好地沉淀,可能會重新入坑
既然重構面臨這么多問題,到底要不要重構?那就問自己願不願意為重構負起責任,堅持到底,並承擔后果。
為什么要重構?
一般說需要重構了,都會是因為面臨着一些問題。近期問題如:不能支持業務、故障、響應不滿足需求、單點無法擴容。長期問題如:維護成本大、擴容成本大、有明顯風險、不支持業務擴展。
我們的代碼迫切的需要重構。我曾經為了申請重構資源,做了很多工作想讓領導認識到我們重構的必要性。嘗試着列舉不重構的話,TOP3無法解決的問題:
1.我們是一個平台系統,當初的設計卻是為了其中一個業務研發的,功能都是定制化的
2.在不合理的邏輯上疊加需求
3.數據模型不能覆蓋目前的需求
不重構很痛,但總感覺沒有說到痛點。后來我們領導說:“重構的目的是為了甩掉歷史包袱。”聽着更接近本質一點了,但是總感覺還是缺少什么。
后來我仔細想了一下。當初必須要重構。因為不重構一改就會出問題。當初資源申請困難是因為我一直都沒解釋清楚為什么一改就出問題。因為按照正常的理解:改出來問題是能力的問題,對業務沒有很好的把控,對代碼沒有深入的研究。而實際上重構是因為”壞味道“使得架構和代碼本身已經無法闡述它的行為。再通俗點說就是:現有架構和代碼,與目前承擔的事情不是一個東西。
為什么要持續重構?
- 從本質上,重構就是在代碼寫好之后改進它的設計。
- 如果你發現自己需要為程序添加一個特性,而代碼結構使你無法很方便地達成目的,那就先重構那個程序,使特性的添加比較容易進行,然后再添加特性。
- 重構改進軟件設計,因為代碼結構的流失是累積性的。
- 重構使軟件更容易理解
- 重構幫助找到bug
- 重構提高編程速度
對我們組來說,為什么要持續重構?
因為持續重構的代碼是確保代碼長期沒有人動,一動就出問題的有效手動。
何時重構?
- 三次法則:事不過三,三則重構。
- 添加功能時重構
- 修補錯誤時重構
- 復審代碼時重構
重構和性能優化
- 重構是對軟件內部結構的一種調整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。它提供了一種更高效且受控的代碼整理技術。
- 和重構一樣,性能優化通常不會改變組件的行為(除了執行速度),只會改變其內部結構。但是兩者出發點不同:性能優化往往使代碼較難理解,但為了得到所需的性能不得不那么做。
”兩頂帽子“如何權衡
在開發過程中,通常會遇到兩頂帽子。一頂是需求的帽子,一頂是重構的帽子。囚徒困境,如何抉擇?
我剛接手交易的時候,對此也很迷惑,所以特地去了解了一下交易的前世今生。了解之前的交易負責人的關注點。有的疲於應付詢問和問題;有的關注需求;重構是解決業務支撐開發量大的有力武器。但是需求來了,怎么辦?
權衡的時候,重要緊急、重要不緊急、緊急不重要、不重要不緊急的四象限理論怎么發揮作用?都緊急的時候怎么按照重要度來進行排序。
回答這個問題就要先弄清楚交易最重要的是什么。交易的核心是穩定。如果重構是維持穩定的必要條件,而我們需要一個重做級別的重構,需要大量的時間。那么這時就需要保證重構和需求至少1:1的投入。
重構的原則
1.測試優先原則
TDD(Test-Driven Development):測試驅動開發
2.OCP原則
Open For Extension:開放封閉原則
3.小步快跑原則
大布局、小迭代
進化式設計和增量開發
避免過度設計,對於未來的變化,既不要考慮的太多,也不能一點都不考慮
代碼滿足當前需求,並留有可擴展余地
4.數據一致性原則
分庫分表(橫向、縱向)
字段合並、冗余
索引優化、數據緩存
重構設計方案選用
技術方案沒有好壞,只有合適不合適。合適的方案用到合適的系統。判斷合適主要考慮的方面:
1.業務契合度
2.覆蓋面全不全
3.擴展性
4.人力投入成本
5.系統穩定性
6.安全
7.簡單明了
重構的注意事項:
- 避免盲目重構
要重構,上面我的內容我自己認為都是需要想清楚的。另外還有一點,需要對重構系統進行一個生命周期預估,包括:
-
- 未來需求預判
- 模塊划分拆解
- 總結歷史問題
- 隱性及顯性需求
我在知乎上看到說怎么判斷隱性需求:隱性需求就是大家都覺得很不爽,但是又說不出個所以然。顯性需求和隱性需求實際上沒區別,視力不同的人看到不同的世界,洞察力不同的人看到不同的需求。
- 割接(新舊系統替換、遷移)實測演練
這塊着重說一下,交易重構的割接采用的是留殼摳瓤的方式。就是對外接口和暴露方式不變,內部逐漸灰度用重構后的系統來替換新系統。
總結與思考:
以前上學的時候最不喜歡遇到主觀題。因為一個試卷上有主觀題,就基本上意味着得不了滿分。 如今工作中,發現自己做的都是主觀題。別人給自己打分,自己給別人打分。說好的標准可能到時候會發現難以實施。說好的加分項,自己也做了很大努力的,結果真正打分的時候,也只能呵呵了。但是通常面對結果,我會對自己說:“我會有一分鍾的不開心,但是我服。”
因為打分的人總有自己的思考過程,得不了滿分總意味自己有改進的地方。犧牲兩周的午飯時間排練的街舞,得了第一名,也就得了一副藍牙耳機。結果其實沒那么重要,只是過程很開心而已。但是經驗與教訓的區別:經驗給出了一條思路,教訓卻給了很多條。
我之前一個同事,自己創業失敗去了我之前工作過的一家公司。后來在美團剛起步的時候加入了美團。做好了之后,如今又去了另外一家剛起步但是很有前景的公司。
我還認識一些人。他們很早買了房子。房價漲了,他們覺得賺了。又繼續買了其他的房子。同樣,價值都在增長。
這些都是成功的經驗得以復制的例子。
教訓的例子卻不太好舉。因為一旦成為教訓,做出的思考很多,采取的改進往往也不是單方面的,得到的提高也往往是綜合的。
如今,我不再怕主觀題。對別人給我打得分,我會給自己一個實質性的收獲。對我給別人打得分,我也會給別人一個滿意的成長。在公司里能夠得到的最大財富就是自身的成長改變,所以感激每一件能讓自己反思自身的事情和經歷。
就像我常說的:人生就是一場游戲,關鍵是經驗值。
跑題時間:
郁金香
桌上的混合花束,和同事談事情的時候無意看了一眼,一支郁金香腦袋耷拉下來。原來這一支插入水中的比較淺,它根部的水已經蒸發掉了。趕緊給添了水,並給這支郁金香擺了個造型支在旁邊的康乃馨上。第二天,這支郁金香又硬挺起來,而且它的花莖還保持着我之前擺的造型,宛然一件藝術品。原來在挫折下可以變得更完美的,不只是人類,也不只是內心。
櫻花
4月是櫻花的季節。記得日本出差的時候,簽證最多只能停留3個月。12月底去的,趕上了日本的成人禮,18歲的姑娘們個個穿着和服趕往廟堂,一片美人海;趕上了情人節,夜晚小樹林里、公園里好多哭哭啼啼的女孩子;卻在只剩下幾天就櫻花祭的時候回國了。所以看到櫻花,心里的感覺總不一樣。
帶着大小情人去公園,看到櫻花。想起新海誠《櫻花抄》里明里看到櫻花時的話:“像雪一樣。”只是櫻花花瓣落於掌心,不會像雪一樣融化。而那年春夏秋冬尋尋覓覓想要在人群中看到的那個人、那些曾經拼命想要忘卻的記憶,竟然像落於掌心的雪花一樣,不見了
蝴蝶蘭
一年四季,前台上總放着一盆蝴蝶蘭。我仔細觀察過,不是塑料花。室內常見的盆栽,自然條件下本來是開花的,養在花盆里卻成了常綠無花的灌木。常說的難以辦到的事情之一就有:“鐵樹開花。”巴西鐵其實卻是可以開花的,只是條件苛刻。而蝴蝶蘭卻總是給人最美的樣子,像是痴痴地等待着一個人。
我用一生等你,你不來我不老。
招賢納士:
美團點評核心交易招收實習生,方向:JAVA開發。要求:19年畢業研究生、985院校優先。有意向請與關注我的公眾號:編程一生,並留言。