Pergunta

Meu projeto contém uma grande quantidade de aulas, um monte de que pode ser descrito por arquivos XML. Não se preocupe, não é a lógica ou implementação em XML. É um jogo, e um exemplo seria que uma telha de jogo pode ser definido em XML, o arquivo de imagem, quadros de animação, etc.

Vou acabar tendo um monte de funções que se parecem com isto:

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

A questão é esta: Se estas funções ser contido em sua própria classe correspondente, por exemplo, o descrito acima seria Foo.FromXml. Ou, devo fazer uma classe separada para ler as coisas a partir de arquivos? Parece haver duas diretrizes gerais concorrentes aqui:

  1. A classe deve saber tudo sobre uma coisa -. Si
  2. Uma classe só deve ter uma razão para a mudança.

Primeiro de tudo, eu realmente não entendo o segundo, porque "razão" é bastante vago. A primeira diretriz sugere colocar cada leitor na classe relacionada. A segunda diz para fazer uma aula dedicada à leitura de arquivos XML. Mas os prós e contras são discutíveis. Por um lado, cada classe pode conter seu próprio leitor, portanto, não há uma dúzia de aulas referenciados. Por outro lado, todas as classes teria que incluir System.Xml, e se eu mudar de formato XML, as coisas podem mudar em vários arquivos (mas eu não acho que isso é muito ruim).

Eu sei que a regra mais importante é "usar seu cérebro" e não existe tal coisa como uma solução "correta", só um bom e um trabalho. Então, o que você acha que seria mais legível, ou ainda melhor, sustentável?

Edit: Para esclarecer, as classes podem ser totalmente alheios. Uma vez que é um jogo, pode ser a classe de animação sprite, pode-se definir o comportamento inimigo, pode-se definir o layout mapa ou propriedades. Assim, a herança não tem nada a ver com isso.

Foi útil?

Solução

Os (...) funções FromXml idênticos? eles Assumindo são eu estaria colocando-o em uma área de biblioteca comum, porque ele vai fazer sua manutenção muito mais fácil que não haverá duplicação de código. O código ainda deve ser limpo também

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

EDIT:. Ou, possivelmente, fazer alguma base classe abstrata que só tem as funções FromXml / ToXml, então tem todas as classes que deseja usar essas funções herdam a classe abstrata

Outras dicas

ter um método de classe base estática para todas as classes que herdam e manter polimorfismo adequada é difícil. Você poderia, contudo, remover a estática-ness do método, e têm um método InitializeFromXml que seria, essencialmente permitem que você preencher sua classe do xml. Embora eu normalmente não se importam para os métodos Inicializar públicos, este tende a ser melhor para o polimorfismo.

aqui está um exemplo. que é um pouco demais para um pequeno objeto como este (e eu raramente realmente usar xml serialização, mas carregá-lo em um documento XML e puxe para fora o que eu preciso para atribuições de desserialização), mas quando as coisas escala, são herdadas, e geralmente mais complexo, que permite reutilizar um pouco mais:

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;
    }
}

A razão que eu favorecer esta abordagem em vez de criar objetos XML serializáveis ??são por causa

  1. xml serialização normalmente exige você estruturar a sua classe de uma maneira, e você normalmente usar esse classe de outra forma.
  2. é um pouco mais fácil do que ter enorme pilhas de XML incluem atributos (Pode ser chamado de algo diferente) em todos os lugares que permitiria a serialização polimórfica de derivado tipos.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top