1. 程式人生 > >大話重構連載10:小設計而不是大布局

大話重構連載10:小設計而不是大布局

開車的朋友一定深有體會,駕駛汽車其實就是在不斷矯正汽車行駛方向的一個過程。在整個駕駛過程中,你必須全神貫注地緊盯前方,通過方向盤不斷矯正方向,否則即使行駛在直線路段也可能偏離車道。那些疲勞駕駛的司機,因為進入睡眠狀態,無法再矯正方向,車輛就會越來越偏離航向。這種情況下,即使數秒鐘的小盹,也能造成車毀人亡的嚴重後果。

重構與駕車雖然屬於完全不同的領域,但其道理是相同的。我們在運用重構方法修改程式碼的過程中也是經常會犯錯的(是人就會犯錯)。犯錯就如同偏離了航向一樣,因此我們需要不斷去矯正。既然是矯正,就必須有一個正確的標準,以及判斷是否正確的方法。駕車過程中正確的標準是車輛是否正確行駛在自己的車道上,判斷是否正確的方法則是司機朋友的目測。同樣地,重構過程中正確的標準是我們的軟體是否保持重構前的外部行為,判斷的方法則是測試,不論是手工測試還是自動化測試。

說起來這個道理很簡單,但問題是你不可能隨時都在測試,隨時都在矯正,這是不可能的。因此,我們必須要有一個週期,即間隔多長時間測試並矯正一次。週期越長,出大問題的機率就越大,就如同那個睡著了的司機;週期越短,我們所需要付出的成本就越高,因為每進行一次測試都是需要我們付出成本的。週期的長短是需要我們去不斷權衡的。

然而,與駕車不同,重構的測試周期還要取決於完成一次重構並提交程式碼的週期。因為軟體重構總是這樣一個過程,首先修改一部分程式碼,使程式處於一個錯誤而無法編譯執行的狀態,然後完全其它所有相關程式碼的修改,使程式恢復編譯可執行的狀態。在這個中間狀態中,我們是無法測試的,或者說測試是無意義的。只有當相關程式碼都修改完成,程式恢復到可執行狀態時,測試才變得有意義。每完成這樣一個過程,我們稱之為“完成一次重構”。而完成一次重構所花費的時間,是決定我們測試周期的關鍵因素。

既然如此,我們完成一次重構到底要花費多少時間呢?這聽起來像是在進行數學推導,但其中的道理就是這樣。決定一次重構花費的時間,是由我們的設計決定的。小設計,我們對程式碼的修改量少,我們完成重構的時間就短;大設計,我們對程式碼的修改量大,我們完成重構的時間必然長。完成重構時間長,測試的週期就長,我們發現錯誤的時間就晚,可能給我們造成的損失必然就大。

大布局為什麼我們傷不起?漫長的業務整理,漫長的設計與開發,持續數月之久。在這數月中我們一直都無法評估自己是否正確。當我們辛苦數月之後才被告知我們犯錯了,一切都為時已晚,專案不得不滑入了失敗的深淵。這就是前面那個故事系統改造失敗的根本原因。

我們說,大布局不可以,但大設計同樣不可能。我開始要重構了,我們思考了很多問題,運用了很多重構手法,來完成一次重構。這樣的重構,程式碼修改量必然多,重構週期必然長,出錯的風險就大。因此,我們的重構應當是一個一個的小設計。運用一個重構手法,解決一個問題,完成一次重構,測試通過,再運用一個重構手法,解決另一個問題,完成另一次重構……如此往復,這就是我在前面所說的“小步快跑”的開發模式。

但是一個我必須要澄清的概念就是,判斷是否是大設計的衡量標準並不是程式碼行數。舉一個簡單例子,我們將一段上千行的程式碼從一個函式,原封不動地挪到另一個函式中,而這段程式碼本身改動很小,這屬不屬於大設計呢?顯然不屬於,因為我們真正修改的程式碼量不多。後面我們將看到,重構過程會經常進行這種程式碼的搬移。

小步快跑讓我們每次重構的時候只關注一個問題,運用一個重構手法去解決這一個問題。這樣就使我們每次在修改問題時不會想得太多太遠。但是,小步快跑並不是要我們完全沒有遠期規劃,不是這樣的。你可以有遠期規劃,但這種規劃不要做得太早,過早做出這些規劃往往容易顧此失彼。先工作一段時間,做一些基礎的工作,讓我們對系統的整體有了一個比較全面地認識,然後再規劃,這樣將得到更好的效果。

同時,它要求我們對遠期的規劃不要過細。越近期的計劃越細,越遠期的規劃越粗。一些人之所以急急匆匆地去做細緻的遠期規劃,是因為擔心今天做出來的東西,到了今後發現不對,得改,所以今天多想想,多規劃一些。但問題是,今天規劃的就正確嗎?如果是當然很好,而現實常常是否。不正確的規劃卻常常適得其反,讓我們陷入一種困境,一種既不能解決當前問題,又不得不為錯誤設計埋單的困境之中。因此重構的思想卻完全打破了這種思維習慣。重構不懼怕修改,因為它讓明天的程式碼修改是安全的,而不再是走鋼絲。它認為,今天的任務就是改今天的,即使到了明天會被認為是錯誤的,也是明天再改去。

特別說明:希望網友們在轉載本文時,應當註明作者或出處,以示對作者的尊重,謝謝!

相關推薦

大話重構連載10設計不是大

開車的朋友一定深有體會,駕駛汽車其實就是在不斷矯正汽車行駛方向的一個過程。在整個駕駛過程中,你必須全神貫注地緊盯前方,通過方向盤不斷矯正方向,否則即使行駛在直線路段也可能偏離車道。那些疲勞駕駛的司機,因為進入睡眠狀態,無法再矯正方向,車輛就會越來越偏離航向。這種情況下,即使數秒鐘的小盹,也能造成車毀人亡的嚴重

大話重構連載19大物件的演化過程

很好,我們終於邁出了重構的第一步,而這第一步我們瞄準了程式碼問題的重災區——超級大函式。超級大函式之所以是程式碼問題的重災區,就是因為它們往往難於閱讀、難於維護。面對大函式我們採取的辦法是拆分,以功能為核心將其拆分成一個一個獨立的函式。拆分後的程式變得易於閱讀了,因為要讀懂程式你不再需要讀完所有程式碼,選擇性

大話重構連載13自動化測試——想說愛你不容易

正如許多事情都有其兩面性一樣,測試方法也是這樣。要保證測試方法正確,最簡單、最直觀地想法就是多寫些測試用例,從更多地角度去測試,但這必然增加我們的測試成本。小步快跑要求我們頻繁進行測試,假如我們重構的週期是20分鐘,但測試卻要花掉10分鐘,那麼這樣的成本就實在太大了。假如這種測試還是開發人員手工測試,每天都有

大話重構連載12你不能沒有保險索

通過前面的描述你已經對重構中“小步快跑”的開發模式有了一個清楚的認識。學會和習慣小步快跑的開發模式,對於重構工作極其重要,因為它讓這種大範圍、大幅度修改程式碼的重構工作變得不再像以往那樣讓人膽戰心驚。究其原因,雖然從結果上是在大範圍、大幅度調整,但每一步卻是小範圍、小福度調整,並且能保證每一步都是正確的。

大話重構連載16超級大函式

事情總是這樣的:當我們對一個遺留系統一忍再忍,再忍,忍,還要忍……終於積攢到某一天,實在忍無可忍了,拍案而起,不能再忍了,重構!!!事情就這樣發生了。然而,在這時你突然發現,重構的工作千頭萬緒,真不知從何開始。堆積如山的問題此起彼伏,期望修改的設計思緒萬千。這裡有個想法,那裡有個思路,什麼都想做,卻什麼都做不

大話重構連載首頁

ooo 我們 family 不能 blank 順序 關系 trac 工廠 《大話重構》這本書是我寫的第一本書,從今天起我將通過連載的形式逐漸跟大家分享。 這本書讓你: 告別遊擊隊轉變為正規軍。 遠離劣質代碼走向精妙設計 真正明確專業級的軟件開發是如

阮一峰Flex 教程實例篇

side web figure title borde 無法 ref .com 1.2 作者: 阮一峰 日期: 2015年7月14日 上一篇文章介紹了Flex布局的語法,今天介紹常見布局的Flex寫法。 你會看到,不管是什麽布局,Flex往往都可以幾行命令搞定。 我只列

微信程序之Flex

設置 兩端對齊 開始 cal spl 不同的 reverse str 一個 微信小程序頁面布局方式采用的是Flex布局。Flex布局,是W3c在2009年提出的一種新的方案,可以簡便,完整,響應式的實現各種頁面布局。Flex布局提供了元素在容器中的對齊,方向以及順序,甚至他

如何設計響應式

nbsp meta標簽 尺寸 type 計算 置1 ice 如何 clas 1、在meta標簽中添加viewport <meta name="viewport" content="width=device-width, initial-scale=1,user-s

微信程序 瀑布流

ear size -m mil item medium app fan height 今天做小程序的時候,碰到一個比較常見的需求,就是要瀑布流布局,兩列,交錯分布,大概如下圖 最終要實現的結果就是如左圖所示。 不過在微信小程序裏面,不能通過JavaScript來直接操

03 Java圖形化界面設計——管理器之FlowLayout(流式

顯示效果 窗口 ext 整數 管理 平移 sflow awt 程序代碼 前文講解了JFrame、JPanel,其中已經涉及到了空布局的使用。Java雖然可以以像素為單位對組件進行精確的定位,但是其在不同的系統中將會有一定的顯示差異,使得顯示效果不盡相同,為

APP界面設計與頁面的23條基本原則

es2017 引導 閱讀 http 技術分享 原則 dmi 區域 慣性 一個App的好與不好,很大部分取決於移動App頁面布局的合理性,優秀的布局顧名思義就是對頁面的文字、圖形或表格等進行排版、設計。 優秀的布局,需要對頁面信息進行完整的考慮,既要考慮用戶需求、用戶行為,也

零元學Expression Blend 4 - Chapter 10 用實例了解容器系列-「StackPanel」

問題 新手 button bsp 使用 arch src ive ane 原文:零元學Expression Blend 4 - Chapter 10 用實例了解布局容器系列-「StackPanel」

微信程序css篇----(Layout)

http 定義 img gpo 定位 display 溢出 watermark text 一:布局有以下幾種:display,float,clear,visibility,overflow,overflow-x,overflow-y。 1.display:設置對象是否顯示。

用Vue來實現音樂播放器(四十)歌單詳情頁以及Vuex實現路由數據通訊

二級 font 利用 imp 實現 map color 音樂 image 1、歌單詳情頁是推薦頁面的二級路由頁面 將推薦頁面歌單的數據傳到歌曲詳情頁面 利用vuex 1、首先在state下定義一個歌單對象 disc{} 2、在mutaions

H5 邊框帶border的百分比

實現 界面 頁面 瀏覽器 就會 但是 gin 添加 bsp 響應式Web設計經常需要我們通過百分比設置組件寬度。如果我們不考慮邊框,那麽很容易就可以實現,但如果你給每一列以及總寬度都采用百分比設置,那這個時候固定的邊框大小就會出來搗亂。下面我們將看到一組方法去解決這個問題,

05 用xml檔案視覺化設計窗口

前面一直用程式碼來設計視窗的佈局,每次修改後,只有程式執行時才可看到設計的結果,而且當視窗的控制元件較多時,寫程式碼的方式較為麻煩了。 所以Android裡還提供了用xml檔案,用視覺化的方式來設計窗口布局. 首先還是先用嚮導建立一個”Add No Act

安卓基礎Activity基礎、五大

Activity: Activity是Android系統中的四大元件之一,可以用於顯示View。它是一種可以包含使用者介面的元件,主要用於和使用者進行互動。 Activity是有生命週期的,每個Activity在其生命週期中最多可能會有四種狀態: Ac

程序JAVA實戰」程序的flex(22)

imageview ner ever program 含義 contain 大小 -m clas 轉自:https://idig8.com/2018/08/09/xiaochengxu-chuji-22/ 之前已經把小程序的框架說完了,接下來說說小程序的組件,在說組件之前

架構的坑系列重構過程中的過度設計

一件事 都是 。。 上層 實現 軟件 太行 事件 -m 架構的坑系列:重構過程中的過度設計 軟件架構 2016-06-03 08:47:02 發布 您的評價: 5.0 收藏 2收藏 這個系列是 坑 系列,