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所需的全部情况.
重构的一种方法是预先传递页面,并将它们传递给受保护的构造函数:
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我不确定这与工厂方法有什么关系。您的帖子说明了模板方法模式。