Theodor
Theodor

Reputation: 5656

Shared singleton instance

I am implementing a program which uses a shared utility class with singleton behavior.

One instance of the utility class is created in the main thread and passed to all other objects instantiated:

SomeUtil util = new SomeUtil();

...

Foo foo = new Foo(util, arg1, arg2)
Bar bar = new Bar(util, arg3, arg4, arg5) 

Is there some more elegant way of achiving this (i.e. design pattern)?

Upvotes: 3

Views: 3789

Answers (5)

merryprankster
merryprankster

Reputation: 3419

Probably the nicest way to get around this is add/use some Dependency Injection framework.

  • framework will guarantee the object indeed is singleton (which has been traditionally a bit tricky especially when done in lazy fashion)
  • you can substitute/control the singleton 'instance' when testing
  • you can get rid off singleton-passed-as-constructor-parameter (if you want to)

Upvotes: 1

Péter Török
Péter Török

Reputation: 116266

As others have mentioned, Singleton can be an alternative. Note though that your current design is easy to unit test (since you are injecting the SomeUtil dependency, which can thus easily be replaced by a mock object during unit tests), while Singleton makes unit testing awkward and difficult:

  • it makes your objects depend on global state, thus it is more difficult to setup your tests correctly, and easy to make mistakes (e.g. by forgetting to initialize the Singleton properly for a specific test),
  • it is more difficult to understand the code since you can't easily identify whether or not a given piece of code is dependent on global state, except by actually reading the whole code.

That being said, if it is a real utility class, i.e. it has no internal state, and it is not dependent on anything which would make unit testing difficult (like a DB, or file system), it can be OK to use it as a Singleton (although this begs the question why do you need to instantiate it at all - usually utility classes have only static methods, and a private constructor to prevent instantiation).

Upvotes: 5

Mark Peters
Mark Peters

Reputation: 81074

Well, you could actually use the singleton pattern which typically stores a static reference to the single instance in the class itself.

public class SomeUtil {
    private static final SomeUtil instance = new SomeUtil();
    public static SomeUtil getInstance() { 
        return instance;
    }
    //...
}

Doing this can make things less unit testable however, so be aware. It's typically much easier to break an injected dependency than a global one.

Upvotes: 3

Vinoth Kumar C M
Vinoth Kumar C M

Reputation: 10598

Why do you pass around utility object? The SomeUtil can have static methods, so that the methods in Foo and bar can use it.

Also, you can implement an actual singleton pattern.

Upvotes: 4

Brian
Brian

Reputation: 6450

Why not just have an actual singleton? Much nicer than passing a single instance around everywhere.

Upvotes: 1

Related Questions