2010-10-14 62 views
1

在我的項目的核心庫,我們有一個非常大的類,它正趨向於成爲一個God object。其中一個原因是,一段時間以來,應該在不同模塊中應用的任務已經投入到這個課程中。對於前 -轉換的公共方法擴展方法

class HugeClass{ 
    public void DoModuleXJob(){} 
    public void DoModuleYJob(){} 
} 

一個在重構的問題和移動沒人要,模塊特定的行爲進行此類的是,這將是一個很多關於模塊的X和Y模塊的工作來改變他們的代碼。 作爲一項工作,我正在考慮將這些方法轉換爲擴展方法,然後將它們移動到其相關模塊。對於前 -

// in module X 
static class HugeClassExtensions{ 
    public static void DoModuleXJob(this HugeClass instance){} 
} 

// in module Y 
static class HugeClassExtensions{ 
    public static void DoModuleYJob(this HugeClass instance){} 
} 

我發現,Y模塊爲不使用DoModuleXJob,反之亦然,這我知道這不會產生任何編譯問題,只要。

這是一個很好的解決方案,並有在這樣的情況下,任何更好的方法?

回答

1

這是個不錯的中間步驟,因爲它至少給你一個劃分出來的功能,並證明有擴展名爲「模塊」之間沒有方法間的依賴關係。這是創建真實子類的第一步,雖然它仍然不理想(你不能單獨實例化模塊類進行單元測試)。

一旦你有了這個分區,它應該更容易創建新的類,因爲你已經確定了模塊邊界。該過程將如下所示:

  1. 傳遞給擴展方法的參數成爲新類的字段,它在構造函數中設置。

  2. 所有的擴展方法成爲新類的方法。

  3. 現在,您可以提取主類的接口,讓子類不再依賴於全面實施。在某些情況下,您可以通過將功能分解爲多個接口來進一步減少依賴關係

  4. 既然您已通過接口進行依賴關係隔離,則可以爲單個模塊編寫單元測試。

0

擴展方法只是一個「語法糖」。您可以定義常用的靜態方法,並使HugeClass實例成爲其中一個參數。 所以它沒有區別。編譯後的CIL文件將是相同的。

+0

是的,但這會打破我想避免的模塊的編譯。 – 2010-10-14 18:33:09

0

我看到您的設計不同,但您爲什麼沒有使用Workflow Foundation 4.0?它很容易和靈活。您可以在工作流程中將代碼編寫爲CodeActivity。我認爲你可以假設一個工作流(活動)作爲一個新的模塊作業,可以添加到核心。

更多了,可以動態生成工作流(活動),這將是非常有用的。

(對不起我的英文不好)

0

我會建議你創建的設計,因爲它應該是,移動是在HugeClass現貨,它應該是功能,然後離開方法調用在HugeClass但有它推遲到功能,它被感動:

class HugeClass 
{ 
    [Obsolete("Use ModuleX.DoModuleXJob() instead", false)] 
    public void DoModuleXJob() { 
     ModuleX mod = new ModuleX(); 
     mod.DoModuleXJob(); 
    } 
} 
class ModuleX 
{ 
    public void DoModuleXJob() { 
    } 
} 

這樣隨着時間的推移,你都採用Facade Pattern與HugeClass。我已經應用到HugeClass方法的Obsolete attribute意味着每次編譯調用HugeClass中的方法時,都會生成警告,指向新功能的位置。屬性中的'false'參數是使其成爲警告的原因,可以將其更改爲true以使其成爲錯誤。通過這種方式,你不會做太多額外的工作,它代表了你想要成爲的進步,我不相信你的擴展方法技術是必須的。隨着時間的推移,HugeClass中的方法可以被刪除,直到它是一個空類並且它自己可以被刪除。

可以肯定的是,如果您還沒有閱讀Martin Fowler的書Refactoring這是一本很棒的閱讀材料。其中他討論了這一點以及其他許多技術。