I just came across an interesting revelation (on the advanced-java list) that points out that Java interfaces can contain inner classes. As an experiment, I whipped together a quick example in which a Customer interface contained a Default implementation and a Factory implementation. This allows factory code to be written as:
Customer c = Customer.Factory.create();This could be replaced with "CustomerFactory.create()", but it seems appropriate to group the customer factory with the customer interface. But the question really becomes: Does this really buy anything? -- PaulPhilion
I guess it would only buy you anything if there was only ever one implementation of an interface in a program, and the factory could be changed somehow.
Or, it might be useful if you could specify an implementation of the interface as an argument to the create method that would be dynamically loaded by the factory.
Customer c1 = Customer.Factory.create("discount"); Customer c2 = Customer.Factory.create("gold-card-scheme");Have you seen it used anywhere?
The problem with the multiple implementation version, above, is that the factory needs to know all possible implementations.
A variation on this would be for the factory to be generic - the argument that it accepts being the class name (as follows): -
Customer c1 = Customer.Factory.create("com.mydomain.mypackage.discount"); Customer c2 = Customer.Factory.create("com.mydomain.mypackage.gold");In this manner, the Factory inner class is pretty bog-standard. It just needs to instantiate a new object of the passed class and return it as a 'Customer'.
-- AdyColes
Well, it would simplify things in some cases by putting things that go together in the same source file. The tradeoff, of course, is against the size of that file.
Another way of looking at it is at the more technical level. Specifically, how does it affect access (visibility)? WRT the interface itself, everything is visible; Factory and Default gain no access to the interface by being inner classes. Factory does gain access to private data and methods in Default. But that could also be accomplished by having Default be an inner class of a non-inner Factory class (with the added advantage that Default could then be private).
Are there other access issues or considerations? -- KielHodges
The point about having Factories is that you want to vary which implementation of the interface is chosen when you need a new object. If there is only to be one implementation, you don't need this.
However, implementations can vary a lot, and by choosing a specific create method of the Factory you say something about the class without committing to a class name nor its location.
You also abstract from initialization procedures.
Factories are just one more means of introducing one level of indirection that lets you vary a specific system aspect that you want to change later on or that varies dynamically. -- DirkRiehle
Customer c=Customer.Factory.create(AwkwardCustomer?.class);Rather than:
Customer c=Customer.Factory.create("org.whatever.somepackage.AwkwardCustomer?.class");Only a minor point, but one which could be considered.
Well, much good input had been provided above. I would just like to point out that Interfaces are typically used to abstract the implementation of a system. A factory (or any concrete code) in an interface would seem to me a violation of the purpose of interfaces. If you need some default implementation for a class, then perhaps an abstract class might be better employed.
While parameterized Factories are pretty widely used, providing the name or the class that you want the factory to instantiate, this seems pretty useless to me, and even perhaps limiting. If you need to specify the class of object to instantiate, then you may as well use the new operator. At least with the new operator, you can pass in needed parameters in the constructor, which could not be done with the Factory.
Typically, you would use the abstract FactoryPattern (consisting of Interfaces for the Factory and its products) to create a (?) to create concrete implementations of products. Therefore, there could be several concrete Factory classes, which would seem to preclude including the concrete Factory in the interface.
What might be an interesting idea, is defining a the Abstract Factory interface, and then defining the abstract product interfaces as inner classes. Anybody have any thoughts on this?
i.e.
public interface Factory {
public interface Product{ String getString1(); } public interface Product{ String getString1(); String getString2(); int getInt(); } Factory.Product1 createProduct1(); Factory.Product1 createProduct2();}
Nathan Pahucki, Design Center Consultant <http://www.silverstream.com/Website/app/en_US/Home>
While parameterized Factories are pretty widely used, providing the name or the class that you want the factory to instantiate, this seems pretty useless to me, and even perhaps limiting. If you need to specify the class of object to instantiate, then you may as well use the new operator. At least with the new operator, you can pass in needed parameters in the constructor, which could not be done with the Factory.
It won't be the case if the class name is passed in from some config files, which allows you to choose among different implementations when deploying the application. [One reason reflection is fun: your object/value/type identities can go outside the type system, e.g. into a config file, and reflection allows them to "come back in".]
Also, I feel that putting Factory inside the Customer is only good so far as to specify the interface of the Factory, i.e. define Customer.Factory.create() to return Customer. Specific factory implementation can then implements Customer.Factory. Then the code responsible for creating the factory can then do a Customer.Factory factory = (Customer.Factory)Class.forName(...).newInstance(), and pass the factory to places that uses it to create Customers. -- OliverChung
I called this the ConstructorObject idiom -- TomAnderson (plug plug)
Arguably, it is a good idea to use interfaces for types, and FactoryPattern to create instances of the type. If you take this approach, you usually end up with either static methods on something (usually an implementation class), or a dedicated factory object (which may or may not use static methods).
If you have a dedicated factory object (Tom's ConstructorObject), you might as well put it in as a static inner class of the interface. This means that you don't have two separate files, and you don't pollute your name space quite so much. However, it makes no serious difference (the only advantage static inner classes have over plain classes is the ability to see the private members, and interfaces don't have any). InterfaceFactories is more of an organizational pattern than anything else.
Note that there is nothing stopping the factory object from being configurable. This, for example, is how Swing works. See AbstractFactoryPattern for more details.