Search code examples
javaclass-design

How to design a class hierarchy which gives information about the subclasses without instantiating it


I'm trying to design classes for spells in a game.

First i have a player with a spelbook, which indicates which spells are available for this player

public class Player {
    private List<Class<? extends Spell>> speellBook;
}

now i created some spells

public abstact class Spell { 
    public abstact double getDmg(); 
    private double position x;
    private double position y;
}
public class FireBolt extends Spell {
    public double getDmg() { return 15; }
}
public class FrostBolt extends Spell {
    public double getDmg() { return 10; }
}

Now i want to show a tooltip about the FireBolt, which shows that this spell does 15 damage whithout instantiating it. It should only instantiated when the player really casts it.

I already thought of a static field but static fields cannot be overidden by the real spells.

Then i thought of an singleton pattern, but since i store the current position in my spells, too, this won't work either

Is there any standard pattern for this? I only found the prototype-pattern but sice i need a singleton it won't be inheritable


Solution

  • You're trying to apply the inheritance (uniformly call getDmg method on different spells) for classes, avoiding objects instantiation. As you already noticed, these requires static fields and a static method, but they do not work with inheritance. I've seen these many times and it does not work in that way.

    I suggest creating template objects and use them for displaying tooltip. Example:

    public class SpellTooltip {
    
        private Map<Class<? extends Spell>, Spell> templates = new HashMap<>();
    
        {
            templates.put(Firebolt.class, new Firebolt());
            templates.put(Frostbolt.class, new Frostbolt());
        }
    
        public int getSpellDamage(Class<? extends Spell> clazz) {
            return templates.get(clazz).getDmg();
        }
    }
    

    The implementation can vary based on the complexity of your design. Using it as-is, you should always remember about adding new types to the map.