杂志/期刊课程结构和/或设计模式

时间:2012-05-17 15:06:12

标签: c# xml class design-patterns

我有一份包含所有校友杂志的xml文件。

<Magazine>
  <Volumes>
    <Volume>
      <Issues>
        <Issue>
          <Sections>
            <Section>
              <Articles>
                <Article>
                  <Images>
                    <Image>
                    </Image>
                    ...
                  </Images>
                </Article>
                ...
              </Articles>
            </Section>
            ...
          </Sections>
        </Issue>
        ...
      </Issues>
    </Volume>
    ...
  </Volumes>
</Magazine>

我创建了一个类:Volume,Issue,Section,Article和Image。

我的问题是:
我应该创建一个超级和子类的层次结构吗? ie - 图像继承文章继承部分继承问题继承卷

我是否将它们分开并使用Generic Collections作为父类的属性?
即 - Volume.Issues,Issue.Sections,Section.Articles,Article.Images

还有其他我完全不知道的东西?

这些选择的利弊/缺陷是什么?

编辑: 如果我使用的是Issue对象,我还需要知道卷号和卷年,以及每个章节中的文章标题。

3 个答案:

答案 0 :(得分:0)

如果所有类都具有公共属性/方法,则可以使用继承,否则继承将毫无意义。

您可以使用Linq To XML从xml文档中获取所需的所有数据,而无需将其映射到类,或在映射后使用Linq to Object

答案 1 :(得分:0)

继承听起来完全错误。只应在域类之间存在自然层次关系时使用它。一个经典的例子是

-Employee 
--Contractor
--Permanent

他们仍然需要名字,地址和类似的方法,如:hire(),fire(),pay()。

在你的情况下,与继承没有任何关系,这是一个典型的例子,说明为什么你应该支持组合优于继承

图片不是文章,但文章是图片。这可以应用于整个结构。

所有关于'有一个'而不是'是一个'。

答案 2 :(得分:0)

只有当您知道如何在应用程序中使用此数据,如何存储数据,如何显示数据等时,确切的答案才会出现。

通常,文章是一个有用的起点类(类似于博客文章等)。你不需要杂志内的文章(而不是MagazineIssue)

    //search all articles in some Magazine issue
    public IList<Article> GetArticles(long ISBN, string issueNumber)
    {
        //implementation
    }

在某些情况下,您也不需要Section类。

public class Article
{
    //can be immutable
    public MagazineIssueView Issue { get; set; }

    public string Author { get; set; }

    public IList<Section> Sections { get; set; }

    public IList<Image> GetAllArticleImages()
    {
        return Sections
            .SelectMany<Section, ContentBlock>(s => s.SectionContent)
            .Where(c => c is Image)
            .Cast<Image>()
            .ToList();
    }
}

public class MagazineIssueView
{
    public long ISBN { get; set; }

    //if you have internal Magazines list, it can be also internal MagazineId
    public string MagazineName { get; set; }

    public DateTime IssueDate { get; set; }

    public string IssueNumber { get; set; }
}

public class Section
{
    public string SectionTitle { get; set; }
    public int Order { get; set; }

    public IList<ContentBlock> SectionContent { get; set; }
}

public abstract class ContentBlock
{
}

public class Image: ContentBlock
{
}

public class Paragraph: ContentBlock
{
}