如何防止工厂方法模式导致构造函数中的虚拟成员调用警告?

com*_*cme 8 c# design-patterns factory-method

www.dofactory.com上,我找到了一个真实的工厂模式示例.但是代码在ReSharper中生成关于构造函数中的虚拟成员调用的警告.

导致警告的代码如下:

abstract class Document
{
    private List<Page> _pages = new List<Page>();

    // Constructor calls abstract Factory method
    public Document()
    {
        this.CreatePages(); // <= this line is causing the warning
    }

    public List<Page> Pages
    {
        get { return _pages; }
    }

    // Factory Method
    public abstract void CreatePages();
}

class Resume : Document
{
    // Factory Method implementation
    public override void CreatePages()
    {
        Pages.Add(new SkillsPage());
        Pages.Add(new EducationPage());
        Pages.Add(new ExperiencePage());
    }
}
Run Code Online (Sandbox Code Playgroud)

在消费代码中,您可以简单地使用:

Document document = new Resume();
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这是一个坏主意,调用构造一个虚拟的成员(如解释在这里).

我的问题是如何重构这个以便仍然使用工厂模式,但没有构造函数中的虚拟成员调用.

如果我只是CreatePages从构造函数中删除调用,则使用者必须显式调用该CreatePages方法:

Document document = new Resume();
document.CreatePages();
Run Code Online (Sandbox Code Playgroud)

我更喜欢创建一个新Resume的实际创建包含页面的Resume所需的全部情况.

das*_*ght 2

重构的一种方法是预先传递页面,并将它们传递给受保护的构造函数:

public abstract class Document {
    protected Document(IEnumerable<Page> pages) {
        // If it's OK to add to _pages, do not use AsReadOnly
        _pages = pages.ToList().AsReadOnly();
    }
    // ...
}

public class Resume : Document {
    public Resume() : base(CreatePages()) {
    }
    private static IEnumerable<Page> CreatePages() {
        return new Page[] {
            new SkillsPage(),
            new EducationPage(),
            new ExperiencePage()
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

PS我不确定这与工厂方法有什么关系。您的帖子说明了模板方法模式

  • @comecme是的,我相当确定他们是错误的:一方面,工厂方法不能是“void”,它必须返回一些东西。 (2认同)