2009-12-03 90 views
2

我的項目包含很多類,其中一些可以用XML文件來描述。別擔心,這不是XML中的邏輯或實現。這是一個遊戲,一個例子是遊戲磁貼可以用XML,圖像文件,動畫幀等來定義。我應該爲此創建一個單獨的類嗎?

我將最終得到一堆看起來像這樣的函數:

public static Foo FromXml(ref XmlTextReader reader) { ... }

問題是這樣的:應這些功能被包含在自身的匹配的類,對於上面的一個例子是Foo.FromXml。或者,我應該爲閱讀文件做一個單獨的課程嗎?這裏似乎有兩個通用的指導原則:

  1. 一個班級應該知道關於一件事的一切 - 本身。
  2. 一個類應該只有一個理由要改變。

首先,我不太瞭解第二個,因爲「原因」很模糊。第一條指南建議將每位讀者放入相關的課程中。第二種說法是讓一個類專門用於讀取xml文件。但是利弊是有爭議的。一方面,每個類可以包含自己的閱讀器,所以不會引用十幾個類。另一方面,每個類都必須包含System.Xml,如果我更改了我的xml格式,事情可能會在多個文件中更改(但我認爲這並不算太糟糕)。

我知道最重要的規則是「用你的大腦」,沒有像「正確的」解決方案那樣的東西,只有一個好的工作的解決方案。那麼你認爲更可讀性更好,還是更好,可維護?

編輯:澄清,類可以完全不相關。由於它是一種遊戲,因此可以是精靈動畫類,可以定義敵人的行爲,也可以定義地圖佈局或屬性。所以繼承與此無關。

+0

考慮一種設計,其中方法不是靜態的,而且它們不使用參數參數。參考文獻往往是代碼氣味(你爲什麼要修改參考?)和靜態方法將呼叫者緊密地耦合到該類。 – TrueWill 2009-12-03 04:37:14

回答

2

FromXml(...)函數是否相同?假設他們是我會把它放在一個共同的圖書館區域,因爲它將使維護他們更容易,因爲不會有代碼重複。該代碼仍然應該整齊太

SomeObject o = (SomeObject)Foo.FromXml(reader); 

編輯:,或者可能使剛剛有FromXml/toxml用於功能的某些抽象基類,然後有需要使用這些功能的所有類從抽象繼承類。

+0

+1:另外,如果它們很少更改,將它們放入一個也是獨立程序集/項目的庫中,然後導入dll。減少構建時間。 – 2009-12-03 03:59:08

+0

ref是因爲爲對象加載的xml可能不是整個文件。它可能是一個已被另一個加載方法讀取的文件塊。所以在閱讀xml的過程中,一個方法可能會看到「哦,這裏有一個精靈」,並將控制權交給精靈加載方法。這有點像一個包括。 – Tesserex 2009-12-03 12:25:07

+0

對不起,這意味着對問題的評論,而不是在這裏。 – Tesserex 2009-12-03 12:25:42

1

擁有所有繼承類的靜態基類方法保持正確的多態性是困難的。但是,您可以刪除該方法的靜態方法,並擁有一個InitializeFromXml方法,該方法實質上允許您從xml填充您的類。雖然我通常不關心公開的初始化方法,但這對多態性來說往往更好。

這裏有一個例子。對於像這樣的小對象來說有點多(我很少實際使用xml序列化,但會將其加載到xml文檔中,並提取我需要的反序列化分配),但是當事物擴展時,會繼承,並且通常更多複雜的,它可以讓你重新使用相當多:

public class CustomObject { 
    public string AValue { get; set; } 
    public bool BValue { get; set; } 
    protected IXmlConfiguration Config = new CustomObjectConfig(); 

    public virtual string ToXml() { 
     return Config.ToXml(this); 
    } 

    public virtual void InitializeFromXml(string xml) { 
     Config.FromXml(xml); 
     AValue = ((CustomObjectConfig)Config).A; 
     BValue = ((CustomObjectConfig)Config).B; 
    } 
} 

public interface IXmlConfiguration { 
    void FromXml(string xml); 
    string ToXml(object instance); 
} 

[XmlRoot("CustomObject")] 
public class CustomObjectConfig : IXmlConfiguration { 
    [XmlElement("AValue")] 
    public string A { get; set; } 
    [XmlAttribute("bvalue")] 
    public bool B { get; set; } 

    public void FromXml(string xml) { 
     byte[] bytes = Encoding.UTF8.GetBytes(xml); 
     using (MemoryStream ms = new MemoryStream(bytes)) { 
      XmlSerializer xs = new XmlSerializer(typeof(CustomObjectConfig)); 
      CustomObjectConfig cfg = (CustomObjectConfig)xs.Deserialize(ms); 
      A = cfg.A; 
      B = cfg.B; 
     }    
    } 

    public string ToXml(object instance) { 
     string xml = null; 
     if (instance is CustomObject) { 
      CustomObject val = (CustomObject)instance; 
      A = val.AValue; 
      B = val.BValue; 
      using (MemoryStream ms = new MemoryStream()) { 
       XmlSerializer xs = new XmlSerializer(typeof(CustomObjectConfig)); 
       xs.Serialize(ms, this); 
       ms.Seek(0, 0); 
       byte[] bytes = ms.ToArray(); 
       xml = Encoding.UTF8.GetString(bytes); 
      } 
     } 
     return xml; 
    } 
} 

我贊成這種辦法,而不是創建XML序列化的對象是因爲

  1. XML序列化通常需要 你組織你的類的原因一種方式, ,你通常會使用那個另一種方式是10班。
  2. 它比其XML的巨大 堆起來更輕鬆的包括屬性 (可稱爲不同的東西) 無處不在,這將允許派生 類型的 多態性序列化。
相關問題