0

I'm making a game in java, and I'm stuck with a design problem. My resources (images, animations, sounds) are stored in a few HashMaps, one for each type of resource. These (static) hashmaps are located in a static class called "Res". When an entity needs a resource, it accesses one of the hashmaps of the global class, and if the resource doesn't exist, it is automatically loaded.

    static Map<String, Sprite> sprites = new HashMap<>();
static Map<String, BufferedImage> images = new HashMap<>();
static Map<String, Clip> sounds = new HashMap<>();
static Map<String, Font> fonts = new HashMap<>();

My question is: Is this design good enough? I've read that static functions are bad practice, but do I have to pass an instance of the class "Res" everytime then? Or are there other alternatives? And also, is this resource management system good practice? Thanks in advance!

Rudy
  • 7,008
  • 12
  • 50
  • 85
user10F64D4
  • 6,531
  • 1
  • 13
  • 12
  • You can use singleton design pattern (static instance under the hood). People like to exaggerate that singletons are bad. In most cases- yes, but in your specific one, using one cache instance in desired situation. – omnomnom Feb 21 '12 at 10:59
  • What is the advantage of singleton over static methods / members? – user10F64D4 Feb 21 '12 at 11:02
  • Singletons preserve the conventional class approach, and don't require that you use the static keyword everywhere. They may be more demanding to implement at first, but will greatly simplify the architecture of your program. – Rudy Feb 21 '12 at 11:18

2 Answers2

0

Use Singleton to maintain all of the resources instead of these static functions.

public class ResourceSingleton {
    private Map<String, Sprite> sprites = new HashMap<>();
    private Map<String, BufferedImage> images = new HashMap<>();
    private <String, Clip> sounds = new HashMap<>();
    private <String, Font> fonts = new HashMap<>();     

    public Map getSprites()
    {return sprites;}

    public void setSprites(Map<String,Sprite> sprites)
    { this.sprites = sprites; } 

    //generate other getter setter

    // Private constructor prevents instantiation from other classes
    private ResourceSingleton() { }


    private static class SingletonHolder { 
            public static final Singleton instance = new Singleton();
            //populate your resource here.
    }

    public static ResourceSingleton getInstance() {
            return SingletonHolder.instance;
    }

}

To use the resource you can just call

ResourceSingleton res = ResourceSingleton.getInstance();
Sprite firstSprite = res.getSprites().get("firstSprite");
Rudy
  • 7,008
  • 12
  • 50
  • 85
0

Keep it simple. As long as you don't need several different instances of your "resource cache", using a static reference is ok.

If you're worried about having to pass around too many references to all kinds of objects in your method calls, you could collect references to all your objects in a "context" object and only pass that one around.

Twilite
  • 873
  • 9
  • 22