Factory implementation - static or instance?


General J2EE: Factory implementation - static or instance?

  1. Factory implementation - static or instance? (6 messages)


    I'm wondering about factories implementation.

    One can write a factory with singleton pattern and factory clients get an instance of the factory,then invoke methods to get target objects.

    The other can write a factory with static methods.In this case factory clients do not have to get an instance of the factory and simply invoking static methods to get target objects.

    I prefer the latter because 1. factory clients( I mean, Java classes that use the factory class ) doesn't need to get an instance of the factory, thus reduce 2 or so lines of their codes. 2. it may achieve better performance due to static methods inlined by compiler optimization.

    Any comments are appreciated.

    Thank you.
  2. 1) How does it reduce lines?
    It's either:

    2) I think the performance gain will be unnoticable, if any. Allmost all the JVMs now perform runtime inlining, and can inline the call when using singletons as well.

    Here is why I prefer singletons:

    1. Lazy initialization can be easily built in into the getInstance() method if the requirement arrises.
    2. It is trivial to support configurable factory implementations allmost without changing any code (just make getInstance() return the configured implementation).
    3. It is possible to dervie factories and use standard OO techniques to implement factories. Static methods are hidden, not overriden, so you can't use any polymorphic techniques in your factory implementation when it is implemented with static methods.
    4. (similar to 3) it is possible to write polymorphic code that uses factories when each factory is an actual object. When the factory is only a class, this is not possible (in the absence of templates).

    Some times you know for sure you're not going to need any of the things above, but I prefer to keep a consistent coding style with such common design patterns, even if it means some extra key-strokes :)

    Just my 5 cents.

  3. I agree with reasons 2-4 100%, but since Java loads class files in a lazy fashion it doesn't really help to add your own lazy instantiation code to the factory, because the static class initialization code is probably run immediately before the first call anyway.

     - Nathan
  4. Nathan,
    I am aware of that technique and you are right, it will work. I usually prefer not to use it (except in special cases such as an alternative to double-checked initialization) for the following reasons:
    1. A Singleton's class may have other static memebers. Constant fields are a good example. This technique will cause the init to run the first time you access such members, which is less efficient. More importantly, it can be very comfusing. You don't have any particular indication the the init code will run, which makes the program harder to debug and maintain.
    2. You can't safely report errors from static initializers. They cannot be declared to throw exceptions, so you're bound to throwing RuntimeExceptions which is messy.
    3. Sometimes you will have a couple of instances instead of just one (i.e: Color will have getBlue(), getYellow(), getRed() ) and there is no reason to init them all at once. You can, but that won't be real lazy initialization :)

    Just my 2 cents.
  5. If you make getInstance() final then all compilers that are any good will inline the code so the extra method call is irrelevant from a performance standpoint.

    An instance is more desirable because:

    1) If in the future you decide to change from Singleton to a thread pool pattern (I have seen this happen) then it's easy to do inside getInstance() and you just have multiple instances of your class. You can't do this with static methods.

    2) It makes it clear to everyone that your class is a singleton, or in some way manages it's own instance lifecycles.

    3) It allows you some polymorphic / inheritance behaviour, which you simply can't do with static methods.

    Just my 2c worth. I'd go with an instance.


  6. Slipped my mind...
    Tony, making the getInstance() method final probably won't change the level of optimization. Static methods are early binded, so the optimizer can inline it anyway. Correct me if I'm wrong :)

  7. Good point. You're right. I'm just in the habit of making everything final that I don't explicitly know I need to extend. That way I have to stop and think about things when I need to over-ride something.

    I'm so into the habit that I do it for statics as well, but you are right, since they _cannot_ be over-ridden then should get in-lined.