views:

336

answers:

3

After some years of experience in the field, it seems to me that the Factory pattern is one of the less interesting and useful patterns around when not writing frameworks or libraries.

I'm not saying that Factory pattern is unnecessary. For example, the W3C Document interface serves as a factory for various XML nodes (elements, attributes, text, ...). The AST class in the Eclipse JDT serves as a factory for ASTNodes like Assignment, MethodDeclaration, etc. I can find many other framework/library examples.

But most of the time, in plain client code, I never feel the need to use Factory pattern. You don't care where the objects come from or how they are created. You just wire up objects through their interfaces with Dependency Injection and afterwards these objects can 'Spring' into life, in a manner dependent on the environment (e.g. new by hand in simple local test, bean container in JEE environment, ...). But never by a Factory, like ArticleFactory.createArticle().

I realize that Spring for example can be considered to be a bean 'factory', but the Spring bean factory is very generic, and the implementation of Factory I'm talking about should have a specific interface and is somehow restricted to creating members of a predefined 'family' of objects.

I also noticed that Factory, Composite, and Visitor often go hand in hand, where the Factory creates a set of (domain-)related objects that a Visitor can traverse. Again, typical stuff for frameworks but not client code.

Therefore, my question is: are there situations, outside of frameworks, where you (would) use Factory pattern instead of plain interfaces and dependency injection? And if so, is there an associated Visitor?

+2  A: 

I use Factory classes (or methods) with some regularity. Perhaps, its a symptom of the Golden Hammer antipattern as Factory happens to be one of the patterns I understand well, but I have found uses. One use I have found recently is injecting a Factory to create LINQ DataContexts as needed for units of work in ASP.NET MVC controllers. By using the Factory, the methods in the controller can use the Factory's methods to create a new DataContext on demand. Combined with Dependency Injection, this gives me both the ability to mock the Factory (and thus the DataContext) and on-demand creation.

tvanfosson
I don't know much about LINQ and DataContexts, but after Googling a while it seems that this falls in the category of frameworks, or extension of.
eljenso
A: 

Factories can be used in combination with dependency injection, where there is a difference in lifetime/lifecycle between the objects that you get from the container, and the objects that those objects use to do their work.

An example:

Lets say you configure a web service through DI and that this web service uses proxies to communicate with other web services.

These proxies need to be closed/disposed ever so often, and live shorter than the web service. Instead of injecting the web service with a proxy (which would result in the lifetime of the proxy to be bound to the web service, ie it cannot be closed while the webservice uses it), you would inject it with an IProxyFactory interface.

that way the web service can ask the IProxyfactory interface to create an IProxy implementation, on which it can delegate the call to the other service. the web service can close/dispose the proxy every time it uses it.

Raymond Roestenburg
Very interesting decoupling. But your primary mechanism here is still DI, even if you are injecting a factory. And isn't the intention of Factory to decouple creation from usage. That doesn't seem to be the motivation here. You also create one object only. Is this a typical usage of Factory?
eljenso
Yes primary is still DI. The intention is also to decouple creation from usage (i left that out a bit), as in being able to change the implementation of the proxy by changing implementation of factory (factory can also itself of course determine some of this).
Raymond Roestenburg
I use this decoupling when i have for instance a client that communicates with services. in testing the client it doesn't communicate with web services, but possibly with mocks or in memory versions of the proxy/service. It also allows for using different types of proxies, generated and dynamic.
Raymond Roestenburg
Oh and in my example, the creation of the object (the proxy) is not done once. Every time a proxy is needed, the factory creates (a new) one.
Raymond Roestenburg
As for typical (apologies for the broken down comments), it is the only way I still use factories. I do everything else through DI, as much as possible transparently to the code (the code not dependent/no refs on/to DI libraries)
Raymond Roestenburg
When I said "create one object only" I actually meant "one *type* of object only". Maybe the terminology about Factory isn't very clear; i.e. Factory is an object that creates an object, Abstract Factory is a pattern for creating related objects. So you really do use a Factory then, not Abstract F.
eljenso
A: 

Perhaps a concrete example would help.

In my CAD/CAM software I have a directory of DLLs each with varying numbers of parametric shapes. All the shapes implement the IParametricShape Interface. Each DLL has a Factory Class that has a single method that returns a collection of IParametricShape. This is added to the software's master list and made available to the user.

The CAD/CAM software is pretty specific to my industry how we also use this for File Types, and Reports. Which are used by many more types of software. You have a list of Report each implementing a IReport interface. You have a factory returning a collection of IReports. You add that your master list of report and make it available to the user. By changing the DLL and the Factory class you can vary the collection and easily add new reports. The same with the type of files you handle.

Finally you can have properties on the interface that allow you to sort out which report (or file type) go where in your software. FOr example I have a collection of Shop Standards Reports which has reports to prints out the customers setup parameters, Another collection of Reports that relate to the Job the customer is dealing with. A property tells me which report is which. Alternatively you can have two separate factory methods one that produce Collection A and another to product Collection B.

RS Conley