views:

2271

answers:

8

My boss always says to use static factory methods, but I'm a beginner and can't understand it.

Please help me.

What's a "static factory method"?

+2  A: 

A factory method a method that abstracts away the instantiation of an object. Generally factories are useful when you know that you need a new instance of a class that implements some interface but you don't know the implementing class.

This is useful when working with hierarchies of related classes, a good example of this would be a GUI toolkit. You could simply hard-code calls to the constructors for concrete implementations of each widget but if you ever wanted to swap one toolkit for another you'd have a lot of places to change. By using a factory you reduce the amount of code you would need to change.

Bryan Kyle
Assuming you have your factory return an interface type, and not the concrete class that you are dealing with.
sharth
+3  A: 

"

  • have names, unlike constructors, which can clarify code.
  • do not need to create a new object upon each invocation - objects can be cached and reused, if necessary.
  • can return a subtype of their return type - in particular, can return an object whose implementation class is unknown to the caller. This is a very valuable and widely used feature in many frameworks which use interfaces as the return type of static factory methods.

"

fromhttp://www.javapractices.com/topic/TopicAction.do?Id=21

Soldier.moth
+4  A: 

Simplified example. We don't want to provide direct access to the connections, because they're resource intensive. So we use a static factory method getDbConnection which creates a connection if we're below the limit. Otherwise, it tries to provide a "spare" connection, and finally fails with an exception if there are none.

EDIT: Made my static factory method actually static. :) (It was intended to be before). Fixed a bug in getDbConnection().

public class DbConnection
{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection()
   {
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection()
   {
     if(totalConnections < MAX_CONNS)
     {
       totalConnections++;
       return new DbConnection();
     }

     else if(availableConnections.size() > 0)
     {
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;
     }

     else
       throw new NoDbConnections();
   }

   public void returnDbConnection(DbConnection db)
   {
     //...
   }
}
Matthew Flaschen
+1  A: 

It all boils down to maintainability. The best way to put this is whenever you use the new keyword to create an object, you're coupling the code you're writing to an implementation.

The factory pattern lets you separate how you create an object from what you do with the object. When you create all of your objects using constructors, you are essentially hard-wiring the code that uses the object to that implementation. The code that uses your object is "dependent on" that object. This may not seem like a big deal on the surface, but when the object changes (think of changing the signature of the constructor, or subclassing the object) you have to go back and rewire things everywhere.

Today factories have largely been brushed aside in favor of using Dependency Injection because they require a lot of boiler-plate code that turns out to be a little hard to maintain itself. Dependency Injection is basically equivalent to factories but allows you to specify how your objects get wired together declaratively (through configuration or annotations).

cwash
Are you saying that factories need a bailout? ;)
jfar
Haha! In this day and age I think we all could use a bailout... :)
cwash
A: 

A static factory method is good when you want to ensure that only one single instance is going to return the concrete class to be used.

For example, in a database connection class, you may want to have only one class create the database connection, so that if you decide to switch from Mysql to Oracle you can just change the logic in one class, and the rest of the application will use the new connection.

If you want to implement database pooling, then that would also be done without affecting the rest of the application.

It protects the rest of the application from changes that you may make to the factory, which is the purpose.

The reason for it to be static is if you want to keep track of some limited resource (number of socket connections or file handles) then this class can keep track of how many have been passed out and returned, so you don't exhaust the limited resource.

James Black
+3  A: 

Readability can be improved by static factory methods:

Compare

public class Foo{
  public Foo(bool withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

to

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();
Rasmus Faber
A: 

a static factory method is:

  • a static method (cannot reference "this" because there is no object)
  • in a class (which may or may not be a static class)
  • that creates and returns some kind of object
Steven A. Lowe
+4  A: 

The factory method pattern is a way to encapsulate object creation. Without a factory method, you would simply call the class's constructor directly: Foo x = new Foo(). With this pattern, you would instead call the factory method: Foo x = Foo.create(). The constructors are marked private, so they cannot be called except from inside the class, and the factory method is marked as static so that it can be called without first having an object.

There are a few advantages to this pattern. One is that the factory can choose from many subclasses (or implementers of an interface) and return that. This way the caller can specify the behavior desired via parameters, without having to know or understand a potentially complex class hierarchy.

Another advantage is, as Matthew and James have pointed out, controlling access to a limited resource such as connections. This a way to implement pools of reusable objects - instead of building, using, and tearing down an object, if the construction and destruction are expensive processes it might make more sense to build them once and recycle them. The factory method can return an existing, unused instantiated object if it has one, or construct one if the object count is below some lower threshold, or throw an exception or return null if it's above the upper threshold.

As per the article on Wikipedia, multiple factory methods also allow different interpretations of similar argument types. Normally the constructor has the same name as the class, which means that you can only have one constructor with a given signature. Factories are not so constrained, which means you can have two different methods that accept the same argument types: Coordinate c = Coordinate.createFromCartesian(double x, double y) and Coordinate c = Coordinate.createFromPolar(double distance, double angle). This can also be used to improve readability, as Rasmus notes.

Jason Owen