Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which design pattern to use to process different files in java?

I have simple task to read the information from different files xml, rdf, txt with different structure and put it in some POJO custom object(MyObject). SO I am wondering which design pattern to use to make my code with better design.

I think on the problem and I think I need Factory Patter and the Iterator Pattern. On the factory to pass the file:

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

So the factory base on the file extension to choose which implemnetation of the iterator to return - these which reads rdf,xml or txt. Then with this iterator I easily can process the objects. Add add new files extensions reading in the future.

like image 686
Xelian Avatar asked Jul 28 '26 01:07

Xelian


1 Answers

Here is an example of how Factory and Strategy could be used. You create one AssetManager (the factory), and register different AssetLoaders (the strategies) along with the file extensions they handle. At runtime, your Factory selects which Strategy to use based on the file extension.

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);
        }
    }
}

All you have to do is create classes that implement the AssetLoader interface for the specific extensions you want to support. Once you have implemented loaders for it, you use it like so:

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

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

You could go one step further, and make it a Singleton, so you don't have to re-register the different loaders every time you want to load another file.

This approach gives a bit more flexibility to support new file types later on. It does add complexity to your code, but if you plan to add support for multiple file types, it might be worth it.

like image 108
Andrew Williamson Avatar answered Jul 30 '26 14:07

Andrew Williamson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!