Handling multiple Object Types - simplifying code possible? (Reading writing xml using JAXB)

60 Views Asked by At

I try to program a text adventure from scratch and I am currently working on save and load functions. I am using JAXB to store every object in a separate XML file.

Since I am handling a lot of different types, I have to create two new functions for each type, resulting in lots of duplicated code.

Is there a way to simplify this? (Most classes share a common super-class, ex. Consumable, Wearable, Weapon, Misc extend Item.)

Or is it better to keep the fully functions separated?

UPDATE: I managed to simplify the save and load functions in Actor Manager. Actor is the super-class and Humanoid and Creature are its sub-classes.

Is it save to do it this way?

But it is not working for ItemManager.

public class ItemManager {

    // Constructor Singleton Pattern
    private ItemManager() { }

    private static class ItemManagerHelper {
        private static final ItemManager INSTANCE = new ItemManager();
    }

    public static ItemManager getInstance() {
        return ItemManagerHelper.INSTANCE;
    }

    // Create
    public Consumable createConsumable(String name, int value, ConsumableType consumableType) throws JAXBException {
        Consumable consumable =
                new Consumable(dataManager.generateId(consumableType.getConsumableType()), name, value, consumableType);

        save(consumable);
        return consumable;
    }

    public Misc createMisc(String name, int value, MiscType miscType) throws JAXBException {
        Misc misc =
                new Misc(dataManager.generateId(miscType.getMiscType()), name, value, miscType);

        save(misc);
        return misc;
    }

    public Weapon createWeapon(String name, int value, WeaponType weaponType) throws JAXBException {
        Weapon weapon =
                new Weapon(dataManager.generateId(weaponType.getWeaponType()), name, value, weaponType);

        save(weapon);
        return weapon;
    }

    public Wearable createWearable(String name, int value, WearableType wearableType) throws JAXBException {
        Wearable wearable =
                new Wearable(dataManager.generateId(wearableType.getWearableType()), name, value, wearableType);

        save(wearable);
        return wearable;
    }

    // Save
    private void save(Consumable consumable) throws JAXBException {
        String type = consumable.getConsumableType().getConsumableType();
        File file = new File(dataManager.getTypePath(type) + consumable.getId() + ".xml");

        JAXBContext context = JAXBContext.newInstance(Consumable.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(consumable, file);
        marshaller.marshal(consumable, System.out);
    }

    private void save(Misc misc) throws JAXBException {
        String type = misc.getMiscType().getMiscType();
        File file = new File(dataManager.getTypePath(type) + misc.getId() + ".xml");

        JAXBContext context = JAXBContext.newInstance(Misc.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(misc, file);
        marshaller.marshal(misc, System.out);
    }

    private void save(Weapon weapon) throws JAXBException {
        String type = weapon.getWeaponType().getWeaponType();
        File file = new File(dataManager.getTypePath(type) + weapon.getId() + ".xml");

        JAXBContext context = JAXBContext.newInstance(Weapon.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(weapon, file);
        marshaller.marshal(weapon, System.out);
    }

    private void save(Wearable wearable) throws JAXBException {
        String type = wearable.getWearableType().getWearableType();
        File file = new File(dataManager.getTypePath(type) + wearable.getId() + ".xml");

        JAXBContext context = JAXBContext.newInstance(Wearable.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(wearable, file);
        marshaller.marshal(wearable, System.out);
    }

    // Load
    public Consumable loadConsumable(String idString) throws JAXBException {
        File file = new File(dataManager.getTypePath(DataManager.typeFromId(idString)) + idString + ".xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Consumable.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Consumable consumable = (Consumable) jaxbUnmarshaller.unmarshal(file);

        System.out.println(consumable);

        return consumable;
    }

    public Misc loadMisc(String idString) throws JAXBException {
        File file = new File(dataManager.getTypePath(DataManager.typeFromId(idString)) + idString + ".xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Misc.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Misc misc = (Misc) jaxbUnmarshaller.unmarshal(file);

        System.out.println(misc);

        return misc;
    }

    public Weapon loadWeapon(String idString) throws JAXBException {
        File file = new File(dataManager.getTypePath(DataManager.typeFromId(idString)) + idString + ".xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Weapon.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Weapon weapon = (Weapon) jaxbUnmarshaller.unmarshal(file);

        System.out.println(weapon);

        return weapon;
    }

    public Wearable loadWearable(String idString) throws JAXBException {
        File file = new File(dataManager.getTypePath(DataManager.typeFromId(idString)) + idString + ".xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Wearable.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Wearable wearable = (Wearable) jaxbUnmarshaller.unmarshal(file);

        System.out.println(wearable);

        return wearable;
    }

}

package Actor;

@SuppressWarnings("unused")
public class ActorManager {
    // Class Variables
    private DataManager dataManager = DataManager.getInstance();

    // Constructor Singleton Pattern
    private ActorManager() { }

    private static class ActorManagerHelper {
        private static final ActorManager INSTANCE = new ActorManager();
    }

    public static ActorManager getInstance() {
        return ActorManagerHelper.INSTANCE;
    }

    // Create
    public Humanoid createHumanoid(String name) throws JAXBException {
        Humanoid humanoid =
                new Humanoid(dataManager.generateId(ActorType.HUMANOID.getActorType()), ActorType.HUMANOID, name);

        saveActor(humanoid);
        return humanoid;
    }

    public Creature createCreature(String name) throws JAXBException {
        Creature creature =
                new Creature(dataManager.generateId(ActorType.CREATURE.getActorType()), ActorType.CREATURE, name);

        saveActor(creature);
        return creature;
    }

    // Save
    private void saveActor(Actor actor) throws JAXBException {
        File file = new File
                (dataManager.getTypePath(actor.getActorTypeString()) + actor.getId() + ".xml");

        JAXBContext context = JAXBContext.newInstance(Creature.class);

        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(actor, file);
        marshaller.marshal(actor, System.out);
    }

    // Load
    private Actor loadActor(String id) throws JAXBException {
        File file = new File(dataManager.getTypePath(DataManager.typeFromId(id)) + id + ".xml");
        Actor actor;
        JAXBContext jaxbContext = JAXBContext.newInstance(Actor.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

        switch(DataManager.typeFromId(id)) {
            case "humanoid":
                actor = (Humanoid) jaxbUnmarshaller.unmarshal(file);
                break;
            case "creature":
                actor = (Creature) jaxbUnmarshaller.unmarshal(file);
                break;
            default:
                System.out.println("ID is not of type Actor. Returning null.");
                actor = null;
        }

        return actor;
    }

    public Creature loadCreature(String id) throws JAXBException {
        return (Creature) loadActor(id);
    }

    public Humanoid loadHumanoid(String id) throws JAXBException {
        return (Humanoid) loadActor(id);

    }
    
}
0

There are 0 best solutions below