天天看點

ActionScript重構三部曲之重構讓世界更美好

這些文章翻譯自Sho Kuwamoto的ActionScript Refactoring 三部曲

本文原文連結在此

        我非常喜歡 Ely的一個作品: DragTile 元件( demo )。 為了做出不同的效果,我想延伸它原有的功能行為,并且使其更具彈性。我第一個想到的就是:Refactoring( 譯注: 中文通常翻譯為:”重構”,為重建立構之意,筆者在此保留原文,免除翻譯的差異 )。 如果你不常或輩子從沒做過refactoring,那麼,且聽我一步步道來,很有趣的。

何謂Refactoring?

Refactoring :在不改變原有外部功能的前提下,以漸進地手法改寫程式碼的結構。”不改變原有功能“聽起來很怪,卻是精随所在。

分成兩部份來看: coding and refactoring,coding階段時,我們加上了新的功能(functionality);refactoring階段,我們重新調整程式碼結構,同時確定功能運作依舊。請牢記”不改變原有功能”的前提,這會讓你在進行調整程式碼時,不會迷失方向,當新的程式碼運作功能與舊的一樣,就是一次成功的refactoring。

有Refactoring有彈性

通常來說,refactoring 要讓現有的程式碼更有彈性,有些時候,你要refactoring的目标很明顯;有些情形下,你必須在refactoring前好好地思考規劃該如何改寫程式碼。

在Ely的例子裡,我們想要讓畫面的照排(layout)方式更容易被改變,看看DragTile的原始碼,有些部份不論照排如何,都是一樣;有些部份随著照排而變動,因為照排的算法(algorithm)在不同案例下會有不同變化,是以我們可以把它抽離出來,獨立成另一個類别(Class)。

Tip 1:

Cleanly separate out the code that you think will need to change often into a separate class.

技巧一: 把你認為會常常變動的程式碼分離出來

我們用繼承的手法,将DragTile裡關于照排的程式碼分開,建立成如下的關系:

ActionScript重構三部曲之重構讓世界更美好

(圖1 繼承)

FlexibleContainer, 負責一般的行為,如: 過場動畫、滑鼠互動等。

DragTile, 負責特定的照排方式,運算物件的位置。

把這些工作分離開後,我們可以更容易地建立新的類别以達成新的照排方式(比如排成一個圓之類的),而其它程式碼:item renderer的溝通、動畫等等還可繼續沿用。

另一個手法:合成(Composition)

ActionScript重構三部曲之重構讓世界更美好

(圖2 合成)

FlexibleContainer是一個容器,它包括了許多子元件,子元件一般行為的程式碼都會在這裡。

TileLayout管理照排的helper Class, 任何照排相關的計算都是它的責任。

如圖所示,Container類别将照排的任務委派(Delegate)給TileLayout來處理,本手法有一些好處:

  1. 以”委派”的觀念實作,通常可以使物件行為得以動态改變。承上,我們可以抽換其中一個Container的照排而不需重新調整繼承關系(reparenting)。
  2. 将大型類别拆解成數個小類别的合成(非繼承),将有助于調整、擴充程式結構,如同各個擊破一般。相對繼承手法來看,如果我們把FlexibleContainer再分離成兩個類别:一個是輕量化的Container專門為下載下傳效率設計;另一個處理快取(cache)、本地化(localization),那麼,DragTile該繼承哪裡一個類别呢? 這将是一個難題,然而,如果你采用了委派的作法,将照排的工作委派給Layout類别,你不會有這個困擾。
  3. 合成手法,通常可以讓系統更分工(decoupling)更具彈性。舉例來說,你正在做照片管理的子產品,如果你用了最上面說的繼承手法,你很難建立一個專門照排的子產品,相對地,用合成手法,照排的功能是可以依使用者需要而直接改變的。

概觀上述所言,有技巧如下:

Tip 2: Think hard before using inheritance. Composition is almost always a better way to separate out the flexible part of a class from the invariant part.

技巧二: 你真的要用繼承嗎? 請三思。合成往往是比較好的選擇。

現在我們有refactoring的基礎概念了,在下一篇我們将深入探讨程式碼。

本文轉自

http://211.147.225.34/gate/gb/blog.shiue.net/?p=502

繼續閱讀