2

私のプロジェクトには多くのクラスが含まれており、その多くは XML ファイルで記述できます。心配する必要はありません。XML のロジックや実装ではありません。これはゲームです。たとえば、ゲーム タイルを XML、画像ファイル、アニメーション フレームなどで定義できます。

私は次のような関数の束を持つことになります:

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

問題は、これらの関数が独自の一致するクラスに含まれている必要があるかどうかです。たとえば、上記の関数は Foo.FromXml になります。または、ファイルから読み取るための別のクラスを作成する必要がありますか? ここで競合する 2 つの一般的なガイドラインがあるようです。

  1. クラスは、1 つのこと、つまりそれ自体についてすべてを知っている必要があります。
  2. クラスを変更する理由は 1 つだけにする必要があります。

まず、2つ目は「理由」があいまいでよくわかりません。最初のガイドラインは、各リーダーを関連するクラスに配置することを提案しています。2 つ目は、xml ファイルの読み取り専用のクラスを 1 つ作成することです。しかし、長所と短所は議論の余地があります。一方では、各クラスに独自のリーダーを含めることができるため、多数のクラスが参照されることはありません。一方、すべてのクラスに System.Xml を含める必要があり、xml 形式を変更すると、複数のファイルで状況が変わる可能性があります (ただし、それほど悪いことではないと思います)。

最も重要なルールは「頭脳を使う」ことであり、「正しい」解決策など存在しないことを私は知っています。では、より読みやすく、さらには保守しやすいものは何だと思いますか?

編集:明確にするために、クラスはまったく無関係である可能性があります。これはゲームなので、1 つはスプライト アニメーション クラスであり、1 つは敵の動作を定義し、1 つはマップ レイアウトまたはプロパティを定義します。したがって、継承はこれとは何の関係もありません。

4

2 に答える 2

2

FromXml(...) 関数は同じですか? それらがそうであると仮定すると、コードの重複がないため、それらを維持するのがはるかに簡単になるため、共通のライブラリ領域に配置します。コードもきちんとしている必要があります

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

編集:または、おそらく、 FromXml / ToXml 関数を持ついくつかの基本抽象クラスを作成し、それらの関数を使用するすべてのクラスが抽象クラスから継承されるようにします。

于 2009-12-03T02:52:23.977 に答える
1

すべての継承クラスに対して静的な基本クラス メソッドを用意し、適切なポリモーフィズムを維持することは困難です。ただし、メソッドの静的性を削除し、InitializeFromXml メソッドを使用して、本質的に xml からクラスを作成できるようにすることができます。通常、パブリックな Initialize メソッドは気にしませんが、ポリモーフィズムにはこれの方が適している傾向があります。

これが例です。このような小さなオブジェクトには少し多すぎます (実際に 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 シリアライゼーションでは、通常、クラスを 1 つの方法で構造化する必要があり、通常はそのクラスを別の方法で使用します。
  2. xml の巨大なスタックに属性 (別のものと呼ばれる場合があります) をどこにでも含めて、派生型のポリモーフィック シリアル化を許可するよりも少し簡単です。
于 2009-12-03T04:47:21.463 に答える