这是我的情景。用户在我的软件中选择一个文档,我的软件从文档中提取一些关键数据。该软件处理两种格式; PDF和DOCX。对于这些类型中的每一种,都有几个模板,并且上传的文档应该属于这些模板之一。我不知道这是否是一个众所周知的问题,是否存在一个既定的设计模式来解决这种情况(这就是为什么我在SO上)。这是我到目前为止设计的内容:
由于每个模板都有特定的结构/内容,我正在考虑为每个模板创建单独的类。将有一个名为IExtractor的顶级接口,然后会有两个名为PdfExtractor和DocxExtractor的顶级类,每个类都实现IExtractor接口。所有PDF(或DOCX)模板共有的任何功能都将进入这些父类。
在这两个父类之下,将有几个模板类,每个模板一个。例如,一个名为Template571_PdfExtractor的类继承自PdfExtractor,它具有特定于Template 571的方法,但提供与任何其他提取器相同形式的结果。
如果重要的话,我正在使用C#4.0。这是骨架:
界面:
interface IExtractor
{
void ExtractDocument(System.IO.FileInfo document, dsExtract dsToFill);
}
两个父类:
public class DocxExtractor : IExtractor
{
public virtual void ExtractDocument(System.IO.FileInfo document, dsExtract dsToFill)
{
}
}
public class PdfExtractor : IExtractor
{
public virtual void ExtractDocument(System.IO.FileInfo document, dsExtract dsToFill)
{
}
}
其中一个具体课程:
public class Template571_PdfExtractor : PdfExtractor
{
public virtual void ExtractDocument(System.IO.FileInfo document, dsExtract dsToFill)
{
}
}
现在有一些我不确定的关键问题。所有这些都围绕着我不知道如何以及在何处实例化具体(模板)类对象的问题。我可以使用文件扩展名来决定是否需要关闭PdfExtractor树节点或DocxExtractor节点。之后,文件的内容告诉我用户文档所属的模板。那么我在哪里放这个“决定”代码?我的想法是将它放在PdfExtractor类(或DocxExtractor)中。这是正确的方法吗?
抱歉,我有点长,但我不知道如何完整描述我的情况。谢谢你的想法。
舒贾特
答案 0 :(得分:1)
一旦你深入挖掘设计模式,你肯定会发现大多数时候没有一种正确的方法来实现某些东西......
一种可能的方法是创建所谓的工厂类:一个用于PdfExtractors,另一个用于DocXExtractors。每个工厂类可能都有一个静态方法,如
public final class PdfExtractorFactory {
public static PdfExtractor getExtractor(String filename) { ... }
... // constructor, or singleton getter here
}
决定要返回的PdfExtractor实例的具体子类(即,使用哪个模板)的逻辑将驻留在工厂方法中。这样,抽象基类PdfExtractor及其子类都不会被这个决策逻辑混乱。只有工厂类需要知道PdfExtractor的子类(resp.DocXExtractor),其余的代码完全没有意识到具体的子类,因为工厂传递了超类的实例。
由于您可能只需要PdfExtractorFactory和DocXExtractorFactory的单个实例,因此您可以选择将这些工厂类实现为单例。
更新:当然,您可以使用静态工厂方法或Singleton模式和非静态工厂方法(但是您不需要两者。)