我应该为此创建一个单独的类吗?

问题描述:

我的项目包含很多类,其中一些可以用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

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

拥有所有继承类的静态基类方法保持正确的多态性是困难的。但是,您可以删除该方法的静态方法,并拥有一个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的巨大 堆起来更轻松的包括属性 (可称为不同的东西) 无处不在,这将允许派生 类型的 多态性序列化。