문제

내 프로젝트에는 많은 클래스가 포함되어 있으며 그 중 많은 수업이 XML 파일로 설명 될 수 있습니다. 걱정하지 마십시오. XML의 논리 나 구현이 아닙니다. 그것은 게임이며, 예를 들어 게임 타일은 XML, 이미지 파일, 애니메이션 프레임 등으로 정의 될 수 있다는 것입니다.

나는 다음과 같은 것처럼 보이는 많은 기능을 갖게 될 것입니다.

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

문제는 다음과 같습니다. 이러한 기능이 자체 일치 클래스에 포함되면 위의 기능은 foo.foomxml입니다. 아니면 파일에서 내용을 읽기 위해 별도의 클래스를 만들어야합니까? 여기에는 경쟁하는 두 가지 일반적인 지침이있는 것 같습니다.

  1. 수업은 한 가지에 대한 모든 것을 알아야합니다.
  2. 수업에는 변경해야 할 이유가 하나만 있어야합니다.

우선, "이유"가 상당히 모호하기 때문에 두 번째를 이해하지 못합니다. 첫 번째 지침은 각 독자를 관련 클래스에 넣는 것을 제안합니다. 두 번째는 XML 파일을 읽는 데 전념하는 한 클래스를 만들라고 말합니다. 그러나 장단점은 논쟁의 여지가 있습니다. 한편으로, 각 수업에는 자체 독자가 포함될 수 있으므로 수십 개의 수업이 참조되지 않습니다. 반면에 모든 클래스에는 System.xml이 포함되어야하며 XML 형식을 변경하면 여러 파일에서 상황이 변경 될 수 있지만 너무 나쁘다고 생각합니다).

나는 가장 중요한 규칙은 "당신의 두뇌 사용"이라는 것을 알고 있으며 "올바른"솔루션과 같은 것은 없으며, 좋은 것만이 많고 일하는 것만이 없습니다. 그렇다면 더 읽기 쉽거나 더 잘 유지할 수 있다고 생각하십니까?

편집 : 명확히하기 위해, 수업은 완전히 관련이 없을 수 있습니다. 게임이기 때문에 스프라이트 애니메이션 클래스 일 수 있으며 적의 행동을 정의 할 수 있으며 맵 레이아웃 또는 속성을 정의 할 수 있습니다. 따라서 상속은 이것과 아무 관련이 없습니다.

도움이 되었습니까?

해결책

Fromxml (...) 함수가 동일합니까? 그들이 코드 복제가 없기 때문에 그것들을 일반적인 라이브러리 영역에 넣을 것이라고 가정 할 때, 나는 그것을 일반적인 라이브러리 영역에 넣을 것이라고 가정합니다. 코드도 여전히 깔끔해야합니다

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

편집하다: 또는 아마도 Fromxml / Toxml 함수를 갖는 기본 추상 클래스를 만들 수 있습니다. 그런 다음 초록 클래스에서 상속 된 함수를 사용하려는 모든 클래스를 사용하십시오.

다른 팁

모든 상속 클래스 및 적절한 다형성을 유지하기위한 정적 기본 클래스 방법을 갖는 것은 어렵습니다. 그러나 메소드의 정적 성을 제거하고 초기화 FROMXML 메소드가있어 본질적으로 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 직렬화는 일반적으로 클래스를 한쪽으로 구성해야하며 일반적으로 다른 방법으로 해당 클래스를 사용해야합니다.
  2. XML의 거대한 스택을 포함하는 것보다 약간 쉽습니다. 이는 파생 유형의 다형성 직렬화를 허용하는 모든 곳에서 속성 (다른 것으로 호출 될 수 있음)을 포함합니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top