views:

206

answers:

4

I'm looking into Guice and I've been reading its documentation recently.

Reading the motivation section I don't understand the factories part, why they name it that way. To me that factory is just a wrapper for the implementing class they want it to return after calling getInstance().

public class CreditCardProcessorFactory {

  private static CreditCardProcessor instance;

  public static void setInstance(CreditCardProcessor creditCardProcessor) {
    instance = creditCardProcessor;
  }

  public static CreditCardProcessor getInstance() {
    if (instance == null) {
      throw new IllegalStateException("CreditCardProcessorFactory not initialized. "
          + "Did you forget to call CreditCardProcessor.setInstance() ?");
    }

    return instance;
  }
}

Why do they call it factory as well if it is neither an abstract factory nor a factory method (at least as they were originally defined by the GoF)? Or am I missing something?

Thanks.

EDIT: if someone comes up with a better title, I'll be glad to change it.

+2  A: 

It's probably just a simplification. Java has a bunch of factory classes which are used like this:

Foo newFoo = FooFactory.getInstance().makeFoo();

... which, in essence, is much the same as in the example. Yes, the Guice example uses a static method rather than a method from a singletong method, but we already know that singletons are little more than a very roundabout way of making static methods and fields. I think they just did something fast to show how bad code can look like, and that they didn't really care about adhering to the GoF pattern canon.

gustafc
In those factory classes you mention, do you have to call setInstance(FooImpl) before? In the Guice's example 'creditCardProcessor' is injected.
Pin
The only class I can come to think of right now is `DocumentBuilderFactory` which has a slightly more advanced way of choosing what `newInstance()` (well, it's *almost* `getInstance()` ;) returns: http://java.sun.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#newInstance%28%29
gustafc
A: 

Ya but there is not any preventtion of instantiation(private constructor), its not completely follow the singleton pattern too.

Let it be here complete code... :)

Rozer
+3  A: 

I've used a similar pattern where code can be given a different class to do something depending on its context. For example if CreditCardProcessor is an interface or an abstract class, high level code wants to set what implementation of it to use, by creating it and passing it to CreditCardProcessorFactory. The using code just gets a CreditCardProcessor without caring what implementation it is.

This bears a resemblance to the Factory pattern because you are getting a CreditCardProcessor without caring about which implementation you have; you just aren't passing any arguments to the factory method (the badly named getInstance() in this case). The implementation you get depends on what other code has set, not what arguments you specify. I may even have called the class I implemented a Factory in this case.

getInstance() and setInstance() are bad names because they make you think of a Singleton. I would have gone with getCreditCardProcessor and setCreditCardProcessor.

DJClayworth
+3  A: 

I'm the author of this doc. I called it a factory for consistency with JDK classes like DocumentBuilderFactory and TransformerFactory. Previous revisions of the example returned a default implementation if setInstance() was never called:

  public static CreditCardProcessor getInstance() {
    if (instance == null) {
      return new SquareCreditCardProcessor();
    }
    return instance;
  }

I changed it to avoid a compile-time dependency from the factory to its implementation. The class has setInstance() because it's simpler than the system properties the JDK uses to select an implementation at runtime.

Since we're trying to motivate dependency injection it may seem unfair to show a fully-featured factory, even if that means being unfaithful to the original GoF pattern.

Jesse Wilson
Hmm, I don't really see how Guice's factory is consistent with DocumentBuilderFactory, for example, which has a factory method but no setInstance like Guice's case. DocumentBuilderFactory appears to comply better with the GoF's pattern I think. But I guess your post best answers my question.
Pin
Well, I can see how someone working with Guice thinking back to the old days before Guice could call this a factory. Jesse, why do you choose a singleton example anyway? It just confuses everybody.
nes1983
I fixed the doc!
Jesse Wilson