13 Replies Latest reply: Jul 1, 2012 7:12 PM by EJP RSS

    Unusual use of interface defining static factory class with getInstance

    rp0428
      This question is prompted by a recent New to Java forum question ask about the differences between Interfaces and Abstract classes. Of course one of the standard things mentioned is that interfaces cannot actually implement a method.

      One of my past clients, one of the 500 group, uses interfaces as class factories. The interface defines a pubic static class with a public static method, getInstance, that is called to generate instances of a class that implements the interface.

      This architecture was very object-oriented, made good use of polymorphism and worked very well. But I haven't seen this architecture used anywhere else and it seemed a little convoluted.

      Here is a 'pseudo' version of the basic interface template and use
      -- interface that defines public static factory class and getInstance method
      public interface abc {
          public static class FactoryClass
          {
              public static abc getInstance ()
              {
                  return (abc) FactoryGenerator(new abcImpl(), abc.class);
              }
          }
      }
      
      -- call of interface factory to create an instance
      abc myABC = abc.Factory.getInstance();
      1. Each main functional area ('abc' in the above) has its own interface factory
      2. Each main functional area has its own implementation class for that interface
      3. There is one generator (FactoryGenerator) that uses the interface class ('abc.class') to determine which implementation class to instantiate and return. The generator class can be configured at startup to control the actual class to return for any given interface.

      I should mention that the people that designed this entire architecture were not novices. They wrote some very sophisticated multi-threaded code that rarely had problems, was high performance and was easy to extend to add new functionality (interfaces and implementing classes) - pretty much plug-n-play with few, if any, side-effects that affected existing modules.

      Is this a best-practices method of designing factory classes and methods? Please provide any comments about the use of an architecture like this.
        • 1. Re: Unusual use of interface defining static factory class with getInstance
          jschellSomeoneStoleMyAlias
          it seemed a little convoluted.
          Good eye.
          Is this a best-practices method of designing factory classes
          Not really. What it is a 'clever' way of implementing a singleton.
          Please provide any comments about the use of an architecture like this.
          You use factories and singletons when the business requirements and design require them. Just as with other patterns.

          Misusing both is possible. With factories a common misuse is when they are over used. That said, it is probably a bit more likely to see convoluted solutions for creation idioms that would have been better solved if factories had been used. (However factories are not always the solution for creation problems.)
          • 2. Re: Unusual use of interface defining static factory class with getInstance
            EJP
            Your pseudo-code is too self-inconsistent to make much sense, but if the interface class contains the name of its own implementation class (abcImpl) I really fail to see the point. The whole idea of the Factory pattern is that you can plug in different factories. I don't see how 'the generator class can be configured at startup to control the actual class to return for any given interface' can possibly be true given this pseudo-code. I don't mind interfaces containing classes per se when necessary, that's not the objection, but the idea of the interface more or less containing its own implementation seems odd.

            @jschell There's nothing here that suggests a singleton to me. The 'new abcImpl()' in fact suggests the opposite. But it's all pretty unclear.
            • 3. Re: Unusual use of interface defining static factory class with getInstance
              rp0428
              Thanks for the feedback.
              >
              I don't see how 'the generator class can be configured at startup to control the actual class to return for any given interface' can possibly be true given this pseudo-code.
              >
              I can see why that isn't clear just from what is posted.
              The way it was explained to me at the time is that the interface uses standard naming conventions and acts like a template to make it easy to clone for new modules: just change 'abc' to 'def' in three places and write a new 'defImpl' class that extends the interface and the new interface and class can just 'plug in' to the framework.

              The new 'defImpl' class established the baseline functionality that must be supported. This line
              return (abc) FactoryGenerator(new abcImpl(), abc.class);
              uses the initial version of the new class that was defined, 'abcImpl()', when calling the FactoryGenerator and it acted as a 'minimum version supported'. The generator class could use configuration information, if provided, to provide a newer class version that would extend this default class. Their reasoning was that this allowed the framework to use multiple versions of the class as needed when bugs got fixed or new functionality was introduced.

              So the initial objects would be an interface 'abc' and a class 'abcImpl'. Then the next version (bug fixes or enhancements) would be introduced by creating a new class, perhaps 'abcImpl_version2'. A configuration parameter could be passed giving 'abcImpl' as the base class to expect in the FactoryGenerator call and the generator would actually create an instance of 'abcImpl_version2' or any other class that extended 'abcImpl'.

              It certainly go the job done. You could use multiple versions of the class for different environments as you worked new functionality from DEV, TEST, QA and PRODUCTION environments without changing the basic framework.

              I've never seen any Java 'pattern' that looks like that or any pattern where an interface contained a class. It seemed really convoluted to me and seems like the 'versioning' aspect of it could have been accomplished in a more straightforward manner.

              Thanks for the feedback. If you wouldn't mind expanding a bit on one comment you made then I will mark this ANSWERED and put it to rest.
              >
              I don't mind interfaces containing classes per se when necessary
              >
              I have never seen this except at this one site. Would you relate any info about where you have seen or used this or when it might be necessary?
              • 4. Re: Unusual use of interface defining static factory class with getInstance
                EJP
                The way it was explained to me at the time is that the interface uses standard naming conventions and acts like a template to make it easy to clone for new modules: just change 'abc' to 'def' in three places and write a new 'defImpl' class that extends the interface and the new interface and class can just 'plug in' to the framework.
                In your pseudo-code there is code in the interface to construct a new abcImpl(). So deploying a new factory means changing that interface. If that's what's meant, it is poor practice. See java.util.ServiceLoader for an example of the right way to do it, with implementation classes named in an external file.
                The generator class could use configuration information, if provided, to provide a newer class version that would extend this default class.
                I would hope so, but that isn't exhibited by your pseudocode.
                I've never seen any Java 'pattern' that looks like that or any pattern where an interface contained a class.
                There are several examples in the JDK. Unfortunately I can't think of them at the moment. ;-)
                It seemed really convoluted to me
                Me too.
                and seems like the 'versioning' aspect of it could have been accomplished in a more straightforward manner.
                It can indeed, see java.util.ServiceLoader.
                • 5. Re: Unusual use of interface defining static factory class with getInstance
                  jschellSomeoneStoleMyAlias
                  EJP wrote:
                  @jschell There's nothing here that suggests a singleton to me. The 'new abcImpl()' in fact suggests the opposite. But it's all pretty unclear.
                  The singleton is the factory not what the factory creates.
                  • 6. Re: Unusual use of interface defining static factory class with getInstance
                    EJP
                    But there is no object. It's just a class with a static method. Not a singleton at all.
                    • 7. Re: Unusual use of interface defining static factory class with getInstance
                      rp0428
                      He might have been referring to this as the factory singleton.
                                  return (abc) FactoryGenerator(new abcImpl(), abc.class);
                      That class is only instantiated one time and is intended to act as a singleton. At startup only one instance got created by the startup code. But there was nothing as I recall that would have prevented a rogue class from creating additional instances of it. So although it performed the role of a singleton I don't believe it was a singleton in the real sense.

                      Thanks to both of you for your comments. Your collective responses provided what I was looking for.
                      • 8. Re: Unusual use of interface defining static factory class with getInstance
                        EJP
                        That's one of the pieces of pseudo code I was unable to understand. It isn't legal Java code so what it is supposed to do is anybody's guess.
                        • 9. Re: Unusual use of interface defining static factory class with getInstance
                          rp0428
                          That's why I didn't want to waste too much time on it. I'm having to rely on memory. It was primarily the use of an interface that included a static method that I hadn't seen before. Interfaces can't include method implementations but this construct alsmost seems to subvert that even though there isn't any actual code in the interface itself.

                          I don't have access to the code that was actually used but I would bet that instead of this
                          return (abc) FactoryGenerator(new abcImpl(), abc.class);
                          It was probably a call to a static method more like this
                          return (abc) FactoryGenerator.staticMethod(new abcImpl(), abc.class);
                          • 10. Re: Unusual use of interface defining static factory class with getInstance
                            EJP
                            In which case it is still just a class with a static method, not a singleton. The factory class is never instantiated at all.
                            • 11. Re: Unusual use of interface defining static factory class with getInstance
                              jschellSomeoneStoleMyAlias
                              EJP wrote:
                              But there is no object. It's just a class with a static method. Not a singleton at all.
                              My definition of "singleton" is looser than the definition expressed as the "Singleton Pattern" in the GoF book.

                              Certainly a 'factory' is in use. I doubt the code refers to multiple instances of a 'factory' class.
                              It might refer to no instances or one instance. Thus it would seem possible that the original coder was attempting a pseudo representation of a singleton.
                              • 12. Re: Unusual use of interface defining static factory class with getInstance
                                jschellSomeoneStoleMyAlias
                                EJP wrote:
                                That's one of the pieces of pseudo code I was unable to understand. It isn't legal Java code so what it is supposed to do is anybody's guess.
                                Indeed.
                                • 13. Re: Unusual use of interface defining static factory class with getInstance
                                  EJP
                                  My definition of "singleton" is looser than the definition expressed as the "Singleton Pattern" in the GoF book.

                                  It might refer to no instances or one instance. Thus it would seem possible that the original coder was attempting a pseudo representation of a singleton.
                                  I prefer my singletons to have one instance, rather than zero, call me old-fashioned.