9

I am trying to implement a Singleton with Java enum.

But I also want to pass some parameters to the constructor when it is initialized for the first time.

How do I achieve that? Is it a good practice to have Singletons with parameter?

public enum DaoManager {
    INSTANCE;
    private static ILog logger; //for passing the logger;
    private static DatabasePool pool; //passing the Database pool

    public void init(ILog logger, DatabasePool pool){
          this.logger = logger;
          this.pool = pool;   
    }

 }

Right now I am using a init method to pass the logger and database pool to DaoManager.

But if client fails to invoke the init() method then there a good chance of failure.

Can someone please guide me on how do I do this?

Sam
  • 2,352
  • 4
  • 32
  • 45

3 Answers3

6

Consider :

public enum DaoManager {
    INSTANCE(FooManager.getLogger(), BarManager.getDataBasePool());
    private static ILog logger; //for passing the logger;
    private static DatabasePool pool; //passing the Database pool

    private DaoManager (ILog logger, DatabasePool pool){
          this.logger = logger;
          this.pool = pool;   
    }

 }

The great thing about enums is that they are similiar to classes.

Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
  • what if `FooManager` or `BarManager` belongs to a library or OS that doesn't provide static method like `getLogger`? – Leo Mar 06 '17 at 23:55
0
public static enum DaoManager {
    INSTANCE;
    private static ILog logger; //for passing the logger;
    private static DatabasePool pool; //passing the Database pool

    public void init(ILog logger, DatabasePool pool){
          this.logger = logger;
          this.pool = pool;   
    }

 }
TheWhiteRabbit
  • 15,480
  • 4
  • 33
  • 57
0

Can I make the init method private?

If there is some kind of initialization logic required for the object to be in a valid state. Then there should be a factory which does this when an object is requested to it.

Having a static init is bad design.

BTW using Singleton is more an anti-pattern for testing. Having a global state makes the object hard to test.

You should not restrict the constructor but make the object singleton with a small 's'. Use some kind of a context object to get the access of the application wide single instance of the DaoManager.

applicationContext.getDaoManager()
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • The initialization is not required for object to be in valid state but we need the logger and database pool to be passed over to other objects. So we have kept it there. Do you think there is anyway we can satisfy this requirement? – Sam Jan 29 '13 at 06:28
  • If you change the object to singleton and dont use enum. Then you can pass it in the constructor. As simple as that. I think it would make more sense. If there is some other requirement then please tell. – Narendra Pathai Jan 29 '13 at 06:30
  • Application wide contexts are great place for you to keep all the application wide singletons. And that should be the way to go. Welcome. – Narendra Pathai Jan 29 '13 at 06:35