Embedded factories

7

I saw this post on needing static methods in an interface (for a factory method) and had a few thoughts.

The first thing it reminds me of is Stefan Schulz’s ideas on adding static contracts to Java as a way to solve this problem. A contract would basically be like an interface of static methods, which seems like something I really want to create about once a year for some reason.

For this particular case, I find this idiom (stolen blatantly from XMLBeans) works pretty well:

public interface Blah {

// methods for the interface

public static class Factory {
public static Blah newInstance() {
return new DefaultBlah();
}
}
}

and callers say:

Blah blah = Blah.Factory.newInstance();

This prevents callers from tying directly to DefaultBlah, leaves the door open for more factory methods (which might do something fancier like dynamically loading an implementation based on a name) in the future, and prevents the extra source file for the factory (if not the factory class).

I used this style for about a year and found it worked pretty well. It does bind your interface to the default implementation, which I find mildly objectionable. In cases where there is an interface and just one implementation (you’re really creating the interface to allow injection, testing, mocking, etc) it works great.

Comments

7 Responses to “Embedded factories”
  1. paulo says:

    My first thought. Bloody stupid. Why would anyone have a dependency on a concrete class on the interface. My second thought: good for library encapsulation, where the users of a library can even NOT know the default class. My third thought : factory and implementations classes package private.

  2. Alex says:

    I didn’t like this the first time I saw it. But all XMLBeans code is generated this way so I used it a lot and eventually we did a fair amount of it in our own code and lived with it for a while and it’s not bad. Really, if you’re gonna make a factory method somewhere, why not tie it closely to the interface?

    When you’re in a code base that uses this pattern, code completion becomes pretty helpful. You don’t need to know about every default impl, just say the interface you want .Factory and a helpful factory method pops up.

    I don’t love it, but it works well in many common situations.

  3. Ted says:

    This is how I’ve done singletons for many years:

    public interface Foo
    {
    // methods for interface Foo …

    static class Singleton
    {
    private static Foo instance;

    public static void set( final Foo foo )
    {
    if( instance == null )
    instance = foo;
    }

    public static Foo get()
    {
    return instance;
    }
    }
    }

    Then, somewhere in bootstrapping of the app (say a ServletContextListener in a webapp):

    Foo.Singleton.set( new FooImpl() );

  4. Caoyuan says:

    Alex,

    Your method is suitable for these singletons. What I encounter is bit a different, the interface and the implementation should be separated in different packages based on in NetBeans Module mechanism, or someting called super package, which is also under a JSP.

  5. Alex says:

    @Ted: Can’t say I like that any better than any other singleton I’ve ever seen… :)

    @Caoyuan: Gotcha, won’t work for that. I’ve been meaning to try out that ServiceLoader stuff for a while….if only I was on Java 6.

  6. This is useful, but on the topic of allowing static methods in interfaces, I ask: Why not.

    It’s very useful not just for this, but also for utility methods that are designed to operate on the interface. For example, I don’t know about you, but in my book, “Collections.sort(someList);” is just an ugly ugly hack. List.sort(someList) would have been better. someList.sort() would have been best. But, because that last one is a lot more difficult to accomplish, List.sort(someList) seems the best for now. But you can’t write that, because you can’t have static methods in interfaces.

    The rules would be simple:

    1. static methods in interfaces -must- be defined, and

    2. If there is a call ambiguity, it’s a compile time error to call it at all.

    #2 exists for an unfortunate coincidence: With defined methods in an interface, combined with the unfortunate rule that in java, even static methods exhibit a certain amount of inheritance (if you extend class X, where X.foobar() is a valid method, than Y.foobar() will also ‘find’ X.foobar), you can create multiple inheritance annoyances.

    e.g:

    public interface X { public static void foobar() {} }

    public interface Y { public static void foobar() {} }

    public class Z implements X, Y {}

    Which foobar is triggered by Z.foobar()?

    That’s what #2 is for. It’s very rare because there aren’t many good reasons to call foobar by invoking Z instead of the real X or Y. It won’t change depending on the runtime instance.

  7. Bob Lee says:

    Nice pattern, Alex! I’ve long wanted to put static factory methods on interfaces, but this is definitely a nice alternative. I don’t know why I didn’t think of putting nested classes in interfaces. This would work equally well for builders.

    I prefer Guice generally, but this will work great in simple situations.

Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!