0

这是我的场景。用户在我的软件中选择了一个文档,我的软件从文档中提取了一些关键数据。该软件处理两种格式;PDF 和 DOCX。对于这些类型中的每一种,都有几个模板,上传的文档应该属于这些模板之一。我不知道这是否是一个众所周知的问题,以及是否存在解决这种情况的既定设计模式(这就是我在 SO 上的原因)。这是我到目前为止设计的:

由于每个模板都有特定的结构/内容,我正在考虑为每个模板创建单独的类。将有一个名为 IExtractor 的顶级接口,然后将有两个名为 PdfExtractor 和 DocxExtractor 的顶级类,每个类都实现 IExtractor 接口。所有 PDF(或 DOCX)模板共有的任何功能都将进入这些父类。

在这两个父类下面,会有几个模板类,每个模板一个。例如,一个名为 Template571_PdfExtractor 的类继承自 PdfExtractor,具有特定于模板 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 )中。这是正确的方法吗?

对不起,我有点长,但我不知道如何完全描述我的情况。谢谢你的想法。

舒贾特

4

1 回答 1

1

一旦您深入研究设计模式等,您肯定会发现大多数时候没有一种正确的方法来实现某些东西......

一种可能的方法是创建所谓的工厂类:一个用于 PdfExtractors,另一个用于 DocXExtractors。每个工厂类可能都有一个静态方法,例如

public final class PdfExtractorFactory {
   public static PdfExtractor getExtractor(String filename) { ... }

   ... // constructor, or singleton getter here
}

决定要返回的 PdfExtractor 实例的具体子类(即使用哪个模板)的逻辑将驻留在工厂方法中。这样,抽象基类 PdfExtractor 及其子类都不会被这个决策逻辑弄乱。只有工厂类需要知道 PdfExtractor 的子类(分别是 DocXExtractor),而您的其余代码将完全不知道具体的子类,因为工厂传递了超类的实例。

由于您可能只需要 PdfExtractorFactory 和 DocXExtractorFactory 的单个实例,因此您可以选择将这些工厂类实现为单例。

更新:当然,您可以使用静态工厂方法或单例模式和非静态工厂方法(但您不需要两者)。

于 2012-07-24T14:08:22.693 回答