rssbandit項目中的collapsiblesplitter作為splitter控件的改進版,提供了我夢寐以求的功能:可以像splitter控件一樣分割兩個相鄰控件,允許在運行時調整他們的大小,還提供了單擊時最小化指定控件的功能,并在小小的分隔條上畫出了相當直觀的精細圖案。
這個控件有不太令人滿意的地方嗎?嗯,有的。它永遠只能有8個像素寬(縱向擺放的時候),不能將它設成splliter默認的4個像素寬,也不能異想天開的將它設成16個像素寬。
打開collapsiblesplitter的代碼文件——我怎么聞到了一股不太美妙的氣味呢?哦,那邊martin fowler同志說了:這是代碼的壞氣味,該給它除除臭。
那么我們就來給它消除異味吧。
先來看看這個玩意到底有些什么壞氣味:
用了太多的switch、if語句,把面向對象的優點拋到爪哇國去了,看看這些代碼吧。這是togglesplitter()方法里的代碼,這個控件中還有很多這樣的代碼:
以下為引用的內容: 代碼1 if(controltohide.visible)![]() ![]() { if(useanimations)![]() { ![]() if(parentform != null)![]() { if(this.dock == dockstyle.left || this.dock == dockstyle.right)![]() { ![]() } else![]() { ![]() } } ![]() } else ![]() { ![]() if(expandparentform && parentform != null)![]() { if(this.dock == dockstyle.left || this.dock == dockstyle.right)![]() { ![]() } else![]() { ![]() } } } } else![]() ![]() { // control to hide is collapsed if(useanimations)![]() { ![]() if(this.dock == dockstyle.left || this.dock == dockstyle.right)![]() { if(parentform != null)![]() { ![]() } ![]() } else![]() { if(parentform != null)![]() { ![]() } ![]() } ![]() } else![]() { // no animations, so just toggle the visible state ![]() if(expandparentform && parentform != null)![]() { if(this.dock == dockstyle.left || this.dock == dockstyle.right)![]() { ![]() } else![]() { ![]() } } } } |
下面的是animationtimertick()方法的代碼(實際上還被俺去掉了幾個if...else...嵌套),有這樣代碼的方法還有三四個:
以下為引用的內容: 代碼2 switch(currentstate)![]() ![]() { case splitterstate.collapsing: if(this.dock == dockstyle.left || this.dock == dockstyle.right)![]() { ![]() } else ![]() { ![]() } break;![]() case splitterstate.expanding: if(this.dock == dockstyle.left || this.dock == dockstyle.right) ![]() { ![]() } else ![]() { ![]() } break; }![]() ![]() |
單個方法內代碼行數太多,且代碼重復率高,如同老婆子般絮絮叨叨、啰唆不清。我們來看看這些長方法的代碼行數和重復率:
togglesplitter()方法,89行,其中重復的語句有
if(parentform != null),3處
if(expandparentform && parentform != null),2處
if(this.dock == dockstyle.left || this.dock == dockstyle.right),4處
if(useanimations),2處
animationtimertick(object sender, system.eventargs e)方法,114行,其中重復的語句有
if(this.dock == dockstyle.left || this.dock == dockstyle.right),2處
if(expandparentform && parentform.windowstate != formwindowstate.maximized && parentform != null),8處
onpaint(painteventargs e)方法,254行,其中重復的語句有
if(hot),4處
if(this.enabled),2處
switch語句(對一個參數進行判斷),2處
臭味如此明顯,更顯除臭工作之必要,呵呵。那我們就開始偉大的除臭工作吧,還有呢,剛才說了“它永遠只能有8個像素寬”,這個特性也不太好啊:對于視力好的人,這個分割條顯得如此之大;而對于有點近視的人呢,它又顯得如此之小。如此,我們自然應該把這個8像素限制去掉。
那現在我們的除臭工作目標訂好了,如下:
去掉這些討厭的、丑陋的、像懶婆娘裹腳布般一層一層又長又臭的switch語句和if語句——即使不能完全去掉也應該把它們集合在一起,而不是到處分散;
去掉這些千篇一律的、到處一樣的、牽一發全身不得不動的重復語句;
縮短這些個超過一屏的、洋洋灑灑的函數代碼,把他們拆到多個方法里面去;
最后,我們希望想這個玩意大的時候它就大,想它小的時候它就小,而不是總是那“8像素”寬(或高)。
新聞熱點
疑難解答