6

I've always known Singletons to be "bad", but only now that I've made the move to Java from C++ have I decided to find a way around them. From a bit of reading, I've found that either Factories or Dependency Injection could possibly do the job, but I'd like some confirmation on this.

As an example, I was about to write a AnimationCache singleton that would store a Map<String, Animation>. Different classes should be able to have access to this class (basically) anywhere so that they can easily and efficiently load Animations. A very brief example of what the equivalent code would look like using DI would be great.

Also, is Guice a good framework for DI with non-web apps? I have used Spring for web development, but I'm not so sure that'd work for games.

Mitch
  • 21,360
  • 9
  • 67
  • 104
  • Spring DI is not only for web apps. – gtiwari333 Aug 22 '11 at 09:56
  • Update: You might also want to consider [CDI 2.0 – Contexts & Dependency Injection for Java](http://cdi-spec.org). Standardized in [JSR 365](https://jcp.org/en/jsr/detail?id=365) as of 2017-04. Designed for *both* Java SE and Java EE. – Basil Bourque May 14 '17 at 07:26
  • This question and its answers may be relevant to future readers: https://stackoverflow.com/questions/130794/what-is-dependency-injection?rq=1 – Cypher Jun 20 '17 at 21:12

3 Answers3

5

Spring and Guice will do fine. I personnally prefer Guice for pure dependency injection, but Spring offers much more.

The code would just look like this:

public class AnimationCacheClient {

    private AnimationCache cache;

    @Autowired // for Spring, or
    @Inject // for Guice (but I think Spring also supports it now)
    public AnimationCacheClient(AnimationCache cache) {
        this.cache = cache;
    }

    // ...
}

I personnally prefer constructor injection, but you might also use setter injection or field injection.

Note that the purpose of DI is not to have "easy singletons", though. Its main purpose is to make the code (of AnimationCacheClient, here) easily unit-estable, by being able to inject mock dependencies (here, a mock AnimationCache instance).

JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
  • Thanks for the code sample. That looks simple enough. So I was wrong in assuming that Dependency Injection can take the place of Singletons? I'm really looking for a better way for code to have access to a class that there should only ever be one of. – Mitch Aug 22 '11 at 09:15
  • No, you weren't wrong. By default, Spring beans are singletons. Guice beans are prototypes by default but may be configured to be singletons. I just wanted to point that the main goal of DI is not to make singletons easy. Its main goal is to make testing easy. – JB Nizet Aug 22 '11 at 10:33
1

Using Spring, DI is very simple. Using the @Autowired annotation, you don't even need additional xml to wire things up or a setter method. A member in the class that needs access to the one that has been your singleton before will do.

Here is a good example: http://www.developer.com/java/other/article.php/3756831/Java-Tip-Simplify-Spring-Apps-with-Autowired.htm

mort
  • 10,940
  • 14
  • 45
  • 92
1

I recently 'withnessed' this thread on Singleton and how bad it might be (or not) and what you can do to bypass it. Well worth the read.

Wivani
  • 2,026
  • 21
  • 27