2013-05-03 151 views
1

讓我們說我們有它的一些方法,其中至少有一個相當複雜性質的一類:如何正確構造函數?

class Example { 
    public function Example() 
    { 
    } 

    private function complexFunction():void 
    { 
     //Do this 
     //And do that 
     //And of course do that 
     //and do not forget that 
    } 

    private function otherImportantFunction():void 
    { 
     //Do something 
    } 

    //[...] 
} 

現在「complexFunction()」已經成長很長,也有點複雜。因此,增加可讀性的一件好事就是在較小的子函數中分割「complexFunction()」。我通常不喜歡這樣寫道:

class Example { 
    public function Example() 
    { 
    } 

    private function complexFunction():void 
    { 
     doThis(); 
     doThat(); 
     andOfCourseDoThat(); 
     andDoNotForgetThat(); 
    } 

    private function doThis():void 
    { 
     //Do This 
    } 

    private function doThat():void 
    { 
     //Do That 
    } 

    private function andOfCourseDoThat():void 
    { 
     //And of course do that 
    } 

    private function andDoNotForgetThat():void 
    { 
     //And do not forget that 
    } 

    private function otherImportantFunction():void 
    { 
     //Do something 
    } 

    //[...] 
} 

但現在的類是在較小的功能,其唯一目的已經淹死在裏面得到調用一次「complexFunction()」。多做一點「分裂」,很難發現所有這些輔助函數之間的重要方法。

至少這是我一直在發生的事情,清晰度真的會受到影響。這讓我想知道你是否知道解決這個難題的方法?當然有辦法或'最佳實踐'來處理這個問題? 我夢想着將功能組合在一起,或者將次要功能從屬於上層功能,而不需要爲此創建一個全新的班級。或者它是如何完成的?

+1

我試着只編寫可重用代碼的函數。如果一個函數只被一個「主函數」調用一次,我不覺得有一個函數是一個好主意。如果你註釋掉你的複雜功能,它可能會更容易閱讀...... – 2013-05-03 12:14:12

+0

如果它在該「主功能」中被多次調用? – 2013-05-03 12:23:41

+0

然後,你顯然不應該重複代碼,但寫一個函數... – 2013-05-03 12:26:10

回答

0

你很對一個大功能分成多個功能。假設它不是像AddOne()而不是value++。特別是你可能會更經常重複的功能可能是有用的。

當你的課堂充滿了多個功能(或者長時間的功能)時,重新考慮你的班級做什麼可能是一個好主意。儘量讓你的課程註定要註冊一門課程。例如,一個類的好主意是讓它與用戶相關。像創建或刪除用戶可以在那裏完成。即使將用戶與例如他們擁有的汽車相匹配也可以在那裏完成。但是不要在保存或刪除Cars的User-class中包含函數。保存一個不同的類。

在這種情況下,您的Example-class將具有User-class和Car-class的實例。如果它看起來像這樣,你高效編程:

class Example { 
    function Example() 
    { 
    } 

    function complexFunction():void 
    { 
     Car newCar = new Car("KK-E8", Color.Red, true); 
     carManager.Add(newCar); 
     User newUser = new User("Moritz", "Krohn", Country.Germany, true); 
     userManager.Add(newUser); 
     newUser.addCar(newCar); 
     ... 
    } 

它發生一些類往往會得到大的,甚至當你試圖保持組織的事情。這絕不是一件壞事,也不是長期的功能。試着讓事情分離,儘量不要重複代碼(爲此創建函數),並嘗試在獨立的類中保留與彼此相關的事物。

+0

這是個好建議!事實上,我能夠從我的大課堂中創造更多的課程。如果真的沒有辦法將結構納入你的年代表以外的其他方法,那麼可能最好有更多的班級,每個班級的責任更少。 – 2013-05-04 08:36:19

0

我個人發現,如果將其分解爲簡單函數,它會提高複雜代碼的可讀性。 我沒有真正得到的代碼是這些簡單的函數組合成一個函數的方式,這似乎只適用於根本不返回任何東西的函數(它們似乎只有一些效果)。更自然的方式來建立一個複雜的功能,從簡單的,將通過功能組成,案例區分或類似的方式......

+0

是的,我同意。我的例子非常簡單。意圖只是爲了直觀地表明具有許多功能使得將重要的功能與幫助功能區分開來變得越來越困難。所以,我會繼續分解函數,但也會在更清晰的地方分裂類。感謝您的回答 :) 。 – 2013-05-04 08:20:53

0

只是因爲一個函數是「長」不會使它更復雜,有些東西只需要很多代碼。
舉個例子:

var loader:Loader = new Loader(); 
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); 
loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); 
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler); 
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler); 
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler); 
loader.contentLoaderInfo.addEventListener(Event.UNLOAD, unLoadHandler); 
loader.contentLoaderInfo.addEventListener(MouseEvent.CLICK, clickHandler); 
var request:URLRequest = new URLRequest(url); 
loader.load(request); 

是不是 「長」?是
它是否具有較高的循環複雜性?沒有
你可以清楚地理解這裏發生了什麼,它很容易遵循。
而且你會發現低CC值的函數/方法總是會更容易閱讀。
另一方面,具有高(+20)CC值的方法應該出現紅旗。
將方法拆分爲單獨的幫助器方法並不能解決問題,並且實際上讓編譯器變得更糟,因爲現在它必須分配專用於那些只會被調用一次的方法的資源。 經驗法則是避免超過20的CC值。
當你達到20以上時,現在是時候開始重新思考你的班級設計,因爲它變得緊密聯繫在一起。

也許你應該問的問題是。

How can I reduce the Cyclomatic Complexity of this? 
+0

好吧,也許這樣的代碼在閱讀時並不難理解,但我認爲這只是長度,如果你不再瞭解你的代碼,它仍然很難找到你正在尋找的東西。所以我仍然會將它分開,並用一個自解釋的函數替換它,如'loadContentAndSetupEventListeners()'。那麼,或許這在這個具體的例子中並沒有太多意義,但是當我真的想讀它時,我更喜歡只讀代碼。 – 2013-05-04 08:30:59

相關問題