2014-03-31 51 views
0

我一直在閱讀重構和用多態性替換條件語句。我遇到的麻煩是,當你有一個更復雜的情況時,對於我來說似乎是有意義的,在沒有多態性的情況下,你將不得不重複相同的開關語句或者重複多次。如果你只做了一次,我不明白它是有意義的 - 你必須有條件的地方,對吧?作爲一個例子,我最近編寫了以下類,它負責讀取XML文件並將其數據轉換爲程序的對象。有2種可能的格式,我們正在支持該文件,所以我只需在類用於處理每一個寫了一方法,和使用的情況下,開關,以確定使用哪一個:有沒有一種很好的方式來使用多態性來刪除這個switch語句?

public class ComponentXmlReader 
{ 
    public IEnumerable<UserComponent> ImportComponentsFromXml(string path) 
    { 
     var xmlFile = XElement.Load(path); 
     switch (xmlFile.Name.LocalName) 
     { 
      case "CaseDefinition": 
       return ImportComponentsFromA(xmlFile); 
      case "Root": 
       return ImportComponentsFromB(xmlFile); 
     } 
    } 

    private IEnumerable<UserComponent> ImportComponentsFromA(XContainer file) 
    { 
     //do stuff 
    } 

    private IEnumerable<UserComponent> ImportComponentsFromB(XContainer file) 
    { 
     //do stuff 
    } 
} 

至於我可以告訴,我可以爲此編寫一個類層次結構來進行解析,但是我沒有看到這裏的優點 - 我仍然必須使用case-switch來確定實例化哪個類。在我看來,如果沒有任何好處,它會變得更加複雜。如果我要保留這些類,並且依賴於文件類型對它們做更多的事情,那麼它將消除在多個地方執行相同的切換,但是這是一次性使用。這是正確的,還是有一些原因或技術,我沒有看到這是一個好主意,使用多態的類層次結構來做到這一點?

回答

0

與所有設計選擇一樣,上下文是關鍵。在這種情況下,你似乎有一個相當簡單的類來處理兩個非常類似的任務。如果兩個Import方法包含非常少的重複代碼,那麼將它們包含在單個類中可能是最好的選擇,因爲如您所說,它可以降低複雜性。

但是,您將來可能會使用此類,甚至可能會添加新類型的導入。在那種情況下,如果類是多態的,那麼這個類將更具可重用性。

此外,由於這些方法聽起來非常相似,因此您可能會有一堆重複的代碼,您可以將它們保留在基類中,並且只將特定於導入的代碼放入子類中。

另外,正如Carl所說,有很多方法可以在不使用case語句的情況下實現這個邏輯。

1

如果你有一個抽象的ComponentImporter類,具體的子類FromA和FromB,你可以實例化其中的一個,並把它放在一個Map中。然後,您可以調用componentImporterMap.get(xmlFile.Name.LocalName).importComponents()並避免切換。

+0

不錯的選擇。要做到這一點,我是不是需要某個地方來放置實例化和地圖構建,比如ComponentImporterFactory,還是CompomentImporterBase中的一些靜態方法? – Mason

+0

是的;根據您的需要,使用地圖的類中的工廠或靜態塊可能是合適的。我不傾向於將工廠放入ComponentImporterBase,但它是一個選項。 –

相關問題