dimanche 27 décembre 2020

Creating objects with a type determined at runtime

I am writing a program that needs to save and load various objects from a file. The files are saved as XML, and I have therefore decided to create an interface called "XMLConvertible" for all the classes that can be converted to XML. When I read the file however, I need to create objects of different types depending on the contents of the XML file.

for example:

<Component></Component>
<Module></Module>

needs to first create an object of type Component, then an object of type Module.

the cleanest way I've encountered so far is to have a Factory with a static list of Builders for all the different classes that can be read from the XML file. Like this (some information has been left out for brevity):

public interface XMLConvertible {
    public void write();
    public void read();
}

public abstract class Factory {
    private static Map<String, Builder> xmlConvertibles = new HashMap<>();

    public static void addXmlConvertible(String key, XMLConvertible value) {
        xmlConvertibles.put(key, value);
    }

    public static XMLConvertible getXmlConvertible(String key) {
        return xmlConvertibles.get(key);
    }
}

public class Component implements XMLConvertible {
    ...
}

public class ComponentBuilder extends Builder {
    static {
        Factory.addXmlConvertible("Component", new ComponentBuilder);
    }

    public Component build() {...}
}

public class Module implements XMLConvertible {
    ...
}

public class ModuleBuilder extends Builder {
    static {
        Factory.addXmlConvertible("Component", new ComponentBuilder);
    }

    public Module build() {...}
}

the problem with this is that I have to create 2 classes for every new XMLConvertible class I add, an actual class and a builder. I would like to either have a way of forcing myself to add a builder so I don't forget, or ideally find a more clean way to implement something like this.

sorry for the long post, I tried to shorten it a bit. Hopefully it is still easy to understand what the problem is.

Aucun commentaire:

Enregistrer un commentaire