1

I want to create a class with few methods which can be used anywhere inside a package. I opted to use enum with a single instance after reading that it automatically provides safe instantiation, serialization and protection from instantiating outside the enum. I believe it is the most easy and safe way of creating a singleton. But my superior came back saying that it's dirty programming. Is it really? Do anyone know the disadvantages of using an enum instead of object construction and passing around references using a class? When are enums initialized?

public enum Myenum {
    INSTANCE;

    public void init(...) {..initialize local variables...}

    public method1 (...) {...}
    public method2 (...) {...}
}

vs

public class Myclass {
    public Myclass(...) {...initialize local variables...}

    public method1 (...) {...}
    public method2 (...) {...}
}

vs

public class Myclass {
    public static void init(...) {...initialize local variables...}

    public static method1 (...) {...}
    public static method2 (...) {...}
}

In my view the disadvantage of using the second method is that an object reference of Myclass is needed everywhere I need to use methods and synchronization issues while object construction. I am not really using the serialization benefit of enum in my case.

Does enum implicitly provide the benefit of dependency injection? (i.e. Can access Myenum's method1, method2 everywhere inside the package without worrying about instance creation)

One other feature of enum I needed was methods inside an enum cannot be overriden outside of it.

Am I missing some obvious disadvantage here?

yalkris
  • 2,596
  • 5
  • 31
  • 51
  • 1
    Did that person explain why they thought it was dirty? Can you ask them? – Sotirios Delimanolis Jun 25 '14 at 19:20
  • No. He is kind of "No matter how good your work is, I have enough experience to not agree with you" ;). One thing he said is it's an alternative to a clean way(creating one object and pass around the reference to it). My thought is if enum implicitly provides many things like I mentioned above why not just use it even though I don't need some of it's benefits(serialization) in my case. Are there any disadvantages of using it this way? – yalkris Jun 25 '14 at 19:28
  • 2
    Unless you're using an Inversion of Control container for your Dependency Injection, your `enum` solution is probably the best. It's not easy to test the `enum` solution because you cannot control what goes into the constructor (if anything). – Sotirios Delimanolis Jun 25 '14 at 19:33
  • My goal is to prevent is both unnecessary reference passing and protecting the instantiation. init is meant to be called only once. How am I instantiating more than once? – yalkris Jun 25 '14 at 19:54
  • You aren't. I was referring to myself. – Origineil Jun 25 '14 at 20:03

3 Answers3

2

An enum gives a semantic signal to other programmers that it's a type with a series of possible values that you could check against, for example, in a switch statement. However, there are a number of compelling reasons why enums can be seen as a better implementation of a singleton pattern than most other patterns people typically use in Java.

If you're positive you want to use a singleton pattern, then using an enum is probably okay. However, there are patterns that tend to be more flexible, unit testable, SOLID, etc. What if one day you decide that you don't actually want this to be a singleton anymore? What if you want it to be refreshable when certain changes are made in the database? Using any singleton pattern is going to lock you into a singleton representation and make it harder to make changes like this in the future.

A Factory pattern would be more flexible than a singleton, but the best pattern of all, in my opinion, would be to use dependency injection. You can singleton-bind your type to avoid the costs of reinstantiating it, but the type itself (and its consumers) need not be tied to a specific lifetime or pattern.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • dependency injection is an answer but it comes with the cost of adding a framework and some complicated code. Enum is an easy way and implicitly provides those things without any extra framework. My goal is to protect the instantiation and unnecessary reference passing. enum methods are protected from being overriden. – yalkris Jun 25 '14 at 20:13
  • @yalkris: Dependency Injection is a pattern that I find works well, and it can be used without a framework, although a framework can help. But it does tend to be an all-or-nothing proposition: once you start using the pattern in one place, you have to use it just about everywhere. A Factory pattern can give you many of the same benefits, without being quite so pervasive. But you know your code base better than I do: if you want a singleton, who am I to argue? ;-) – StriplingWarrior Jun 25 '14 at 20:40
0

I found an answer here to why creating a globally accessible pattern is bad instead of passing around references.

Excerpt:

  1. They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.

  2. They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.

  3. They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.

  4. They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Community
  • 1
  • 1
yalkris
  • 2,596
  • 5
  • 31
  • 51
0

Check out Java Concurrency In Practice and it's static singleton pattern. It looks like this:

public class ResourceFactory {
    private static class ResourceHolder {
        public static Resource resource = new Resource();
    }

    public static Resource getResource() {
        return ResourceHolder.resource;
    }
}

It's safe due to how/when statics are initialized, probably for the same reasons the Enums singleton trick is safe.

In JCIP's example, it's returning a thing, but you can add all the static methods you want that use however many variables you want to initialize in the ResourceHolder. And there's no init() call required.

Chris Kessel
  • 5,583
  • 4
  • 36
  • 55
  • It serves one of the goals of my usage of singleton(global methods which can accessed everywhere inside a package) but there are equal or more disadvantages of using a singleton as an alternative to passing around references. – yalkris Jul 07 '14 at 15:37