在java中使用哪种设计模式来处理不同的文件?

时间:2016-02-01 19:47:11

标签: java xml design-patterns rdf

我有一个简单的任务来读取具有不同结构的不同文件 xml,rdf,txt 中的信息,并将其放在一些 POJO 自定义对象(MyObject)中。所以我想知道使用哪种设计模式来使我的代码具有更好的设计。

我想问题,我认为我需要 Factory Patter Iterator Pattern 。 在工厂传递文件:

ReaderFactory factory = new ReaderFactory("input.rdf");
//ReaderFactory factory = new ReaderFactory("input.xml");
Iterator<MyObject> iter = factory.getIterator();

因此工厂基于文件扩展名来选择返回迭代器的实现 - 这些读取rdf,xml或txt。然后使用这个迭代器,我可以轻松地处理对象。添加添加新文件扩展名,以便将来阅读。

3 个答案:

答案 0 :(得分:3)

最好将您的解决方案视为一种设计模式,而不是将设计模式视为您的解决方案。

如果您已经考虑过这一点,那么我认为,Strategy模式可能更适合您的情况。

我假设您读取输入文件的方式将保持不变,无论文件格式如何。但您可能希望根据文件的内容构建POJO。

例如:

interface FileProcessor {
 public POJO process(BufferedReader br);
}

可以跨类实现相同的接口。

class RDFFileProcessor implements FileProcessor {
 public POJO process(BufferedReader br) {
  // do your processing logic for rdf file content.
  return POJO;
 }
}

答案 1 :(得分:2)

以下是如何使用工厂策略的示例。您创建一个AssetManager(工厂),并注册不同的AssetLoader(策略)以及它们处理的文件扩展名。在运行时,您的 Factory 会根据文件扩展名选择要使用的策略

public interface AssetLoader
{
    public Object load(String name) throws Exception;
}

public class AssetManager
{
    private HashMap<String, AssetLoader> loaders = new HashMap<>();

    public void addLoader(AssetLoader loader, String extension)
    {
        loaders.put(extension, loader);
    }

    @SuppressWarnings("unchecked")
    public <T> T load(String name)
    {
        int i = name.lastIndexOf('.');
        if (i == -1)
            throw new RuntimeException("\"" + name + "\" has no extension, and so has no associated asset loader");

        String extension = name.substring(i+1);
        AssetLoader loader = loaders.get(extension);
        if (loader == null)
            throw new RuntimeException("No loader registered for \"." + extension + "\" files");
        try
        {
            return (T) loader.load(name);
        }
        catch(ClassCastException e)
        {
            throw new RuntimeException("\"" + name + "\" could not be loaded as the expected type");
        }
        catch(Exception e)
        {
            throw new RuntimeException("Failed to load " + name, e);
        }
    }
}

您所要做的就是创建为您想要支持的特定扩展实现AssetLoader接口的类。一旦你为它实现了加载器,就像这样使用它:

AssetManager assets = new AssetManager();
assets.addLoader(new JsonLoader(), "json");
assets.addLoader(new XmlLoader(), "xml");

Iterator<MyObject> iter = assets.load("input.xml");

您可以更进一步,并使其成为 Singleton ,这样您就不必在每次要加载其他文件时重新注册不同的加载器。

这种方法可以更灵活地支持以后的新文件类型。它确实增加了代码的复杂性,但如果您计划添加对多种文件类型的支持,那么它可能是值得的。

答案 2 :(得分:1)

我认为你应该停止尝试重新发明轮子。至少使用已解决此问题的RDF4jJena来阅读RDF。我推荐使用RDF4j而不是耶拿,它更容易使用,但两者都可以正常使用。

然后你可以使用Pinto(免责声明,我是作者)之类的东西将解析后的文件映射到POJO,类似于Jackson&amp; JSON。

RDF4j和Jena都在他们的网站上有关于如何使用他们的解析器的良好文档。我知道RDF4j会根据文件扩展名选择正确的解析器,这就是你所说的。

节省一些时间和精力,使用库为您完成此操作并实际专注于您的应用程序。