Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Factory pattern (or at least the use of FactoryFactory..) is the butt of many jokes, like here.

Apart from having verbose and "creative" names like RequestProcessorFactoryFactory.RequestProcessorFactory, is there anything fundamentally wrong with the factory pattern if you have to program in Java/C++ and there is a usecase for Abstract_factory_pattern?

How would another popular language (for example, Ruby or Scala) avoid having to use it while managing similar complexity?

The reason I am asking is I see mostly the criticism of factories mentioned in the context of the Java/Java EE ecosystem, but they never explain how other languages/frameworks solve them.

share|improve this question
    
possible duplicate of Where are all the functional programming design patterns? –  gnat Apr 16 at 10:38
3  
The problem isn't the use of factories -- it's a perfectly fine pattern. It's the overuse of factories which is especially prevalent in the enterprisey java world. –  CodesInChaos Apr 16 at 15:42
    
Very nice joke link. I would love to see a functional language interpretation of retrieving the tools to build a spice rack. That would really drive it home, I think. –  Patrick M Apr 16 at 20:04

5 Answers 5

As so often, people misunderstand what's going on (and that includes many of the laughers).
It's not the factory pattern per se that's bad as much as the way many (maybe even most) people use it.

And that no doubt stems from the way programming (and patterns) is taught. Schoolkids (often calling themselves "students") get told to "create X using pattern Y" and after a few iterations of that think that that's the way to approach any programming problem.
So they start applying a specific pattern they happen to like in school against anything and everything, whether it's appropriate or not.

And that includes university professors who write books about software design, sadly.
The culmination of this was a system I had the distinct displeasure of having to maintain which had been created by one such (the man even had several books about object oriented design to his name, and a teaching position in the CS department of a major university).
It was based on a 3 tier pattern, with each tier itself a 3 tier system (have to decouple...). On the interface between each set of tiers, on both sides, was a factory to produce the objects to transfer data to the other tier, and a factory to produce the object to translate the received object to one belonging to the receiving layer.
For each factory there was an abstract factory (who knows, the factory might have to change and then you don't want the calling code to have to change...).
And that whole mess was of course completely undocumented.

The system had a database normalised to 5th normal form (I kid you not).

A system that was essentially little more than an address book that could be used to log and track incoming and outgoing documents, it had a 100MB codebase in C++ and over 50 database tables. Printing 500 form letters would take as long as 72 hours using a printer connected directly to the computer running the software.

THAT's why people scoff patterns, and specifically people focusing singlemindedly on a single specific pattern.

share|improve this answer
34  
The other reason being that some of the Gang of Four patterns are just really verbose hacks for things that can be done trivially in a language with first-class functions, which kind of makes them unavoidable anti-patterns. "Strategy", "Observer", "Factory", "Command" and "Template Method" patterns are hacks to pass functions as arguments; "Visitor" is a hack to perform a pattern match on a sum type/variant/tagged union. The fact that some people make much ado about something that's literally trivial in many other languages is what leads people to mock C++, Java and similar languages. –  Doval Apr 16 at 12:02
4  
Thank you for this anecdote. Can you also elaborate a bit on the "what are the alternatives?" part of the question so we don't become like that too? –  Philipp Apr 16 at 12:28
1  
@Doval Can you tell me how do you return value from executed command or called strategy when you can only pass function? And if you say closures, then keep in mind it is exactly same thing as creating a class, except more explicit. –  Euphoric Apr 16 at 12:38
2  
@Euphoric I'm not seeing the problem, can you elaborate? In any case, they're not exactly the same thing. You might as well say than an object with a single field is exactly the same as a pointer/reference to a variable or that an integer is exactly the same as a (real) enum. There's differences in practice: it makes no sense to compare functions; I've yet to see a concise syntax for anonymous classes; and all functions with the same argument and return types have the same type (unlike classes/interfaces with different names, which are different types even when they're identical.) –  Doval Apr 16 at 12:58
2  
@Euphoric Correct. That would be considered bad functional style if there's a way to get the job done without side effects. A simple alternative would be to use a sum type/tagged union to return one of N kinds of values. Regardless, let's assume there is no practical way; it's not the same as a class. It's actually an interface (in the OOP sense.) It's not hard to see if you consider that any pair of functions with the same signatures would be interchangeable, while two classes are never interchangeable even if they have the exact same contents. –  Doval Apr 16 at 15:06

Your question is tagged with "Java", no surprise you're asking why is the Factory pattern being mocked: Java itself comes with a nicely packaged abuses of that pattern.

For example try loading an XML document from a file and run an XPath query against it. You need something like 10 lines of code just to setup the Factories and Builders:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder(); 

Document xmlDocument = builder.parse(new FileInputStream("c:\\employees.xml"));
XPath xPath =  XPathFactory.newInstance().newXPath();

xPath.compile(expression).evaluate(xmlDocument);

I wonder if the guys designing this API ever worked as developers or did they just read books and throw things around. I understand they just didn't want to write a parser themselves and left the task to others but it still makes for an ugly implementation.

Since you're asking what's the alternative here's loading the XML file in C#:

XDocument xml = XDocument.Load("c:\\employees.xml");
var nodes = xml.XPathSelectElements(expression);

I suspect newly hatched Java developers see the Factory madness and think it's OK to do that - if the geniuses who built Java themselves have used them that much.

Factory and any Other patterns are tools, each suited for a particular job. If you apply them to jobs they aren't suited for you're bound to have ugly code.

share|improve this answer
5  
+1 for the side-by-side comparison. –  Doval Apr 16 at 13:58
    
thanks(+1), also for a practical comparison. –  zencv Apr 16 at 14:19
    
Just a note that your C# alternative is using the newer LINQ to XML - the older DOM alternative would have looked something like this: XmlDocument xml = new XmlDocument(); xml.Load("c:\\employees.xml"); XmlNodeList nodes = xml.SelectNodes(expression); (Overall, LINQ to XML is far easier to use, though mostly in other areas.) And here's a KB article I found, with a MS-recommended method: support.microsoft.com/kb/308333 –  Bob Apr 17 at 8:24

Factories have many advantages which allow for elegant application designs in some situations. One is that you can set the properties of objects you later want to create in one place by creating a factory, and then hand that factory around. But often you don't actually need to do that. In that case using a Factory just adds additional complexity without actually giving you anything in return. Let's take this factory, for example:

WidgetFactory redWidgetFactory = new ColoredWidgetFactory(COLOR_RED);
Widget widget = redWidgetFactory.create();

One alternative to the Factory pattern is the very similar Builder pattern. The main difference is that the properties of the objects created by a Factory are set when the Factory is initialized, while a Builder is initialized with a default state and all properties are set afterwards.

WidgetBuilder widgetBuilder = new WidgetBuilder();
widgetBuilder.setColor(COLOR_RED);
Widget widget = widgetBuilder.create();

But when overengineering is your problem, replacing a Factory with a Builder is likely not much of an improvement.

The most simple replacement for either pattern is of course to create object-instances with a simple constructor with the new operator:

Widget widget = new ColoredWidget(COLOR_RED);

Constructors, however, have a crucial drawback in most object-oriented languages: They must return an object of that exact class and can not return a sub-type.

When you need to choose the sub-type at runtime but don't want to resort to creating a whole new Builder or Factory class for that, you can use a factory-method instead. This is a static method of a class which returns a new instances of that class or one of its sub-classes. A Factory which does not maintain any internal state can often be replaced with such a factory-method:

 Widget widget = Widget.createColoredWidget(COLOR_RED); // returns an object of class RedColoredWidget

A new feature in Java 8 are method references which allow you to pass methods around, just like you would do with a stateless factory. Conveniently, anything which accepts a method reference also accepts any object which implements the same functional interface, which can also be a full-fledged Factory with internal state, so you can easily introduce factories later, when you see a reason for doing so.

share|improve this answer
1  
A factory can often also be configured after creation. The major difference, afaik, to a builder is that a builder is typically used to create a single, complex instance, while factories are used to create many similar instances. –  Arian Apr 16 at 12:03
    
thanks(+1), but the answer fails to explain how other PLs would solve it, nevertheless thanks for pointing out Java 8 method references. –  zencv Apr 16 at 14:17
1  
I've often thought that it would make sense in an object-oriented framework to limit actual object construction to the type in question, and have foo = new Bar(23); be equivalent to foo = Bar._createInstance(23);. An object should be able to reliably query its own type using a private getRealType() method, but objects should be able to designate a supertype to be returned by outside calls to getType(). Outside code shouldn't care whether a call to new String("A") actually returns an instance of String [as opposed to e.g. an instance of SingleCharacterString]. –  supercat Apr 16 at 17:31
1  
I use a lot of the static method factories when I need to choose a subclass based on context but the differences should be opaque to the caller. For example I have a series of image classes that all contain draw(OutputStream out) but generate slightly different html, the static method factory creates the right class for the situation and then the caller can just use the draw method. –  Michael Shopsin Apr 16 at 17:33
1  
@supercat you might be interested in taking a look at objective-c. There construction of objects consists of simple method calls, usually [[SomeClass alloc] init]. It's possible to return a completely different class' instance or another object (such as a cached value) –  axelarge Apr 18 at 6:23

Factories of one sort or another are found in pretty much any object-oriented language under appropriate circumstances. Sometimes you just plain need a way to select what kind of object to create based on a simple parameter like a string.

Some people take it too far and try to architect their code to never need to call a constructor except inside a factory. Things start to get ridiculous when you have factory factories.

What struck me when I learned Scala, and I don't know Ruby, but believe it is much the same way, is that the language is expressive enough that programmers aren't always trying to push the "plumbing" work to external configuration files. Rather than being tempted to create factory factories to wire your classes together in different configurations, in Scala you use objects with traits mixed in. It's also relatively easy to create simple DSLs in-language for tasks that are often way over-engineered in Java.

Also, as other comments and answers have pointed out, closures and first class functions obviate the need for many patterns. For that reason, I believe many of the anti-patterns will start disappearing as C++11 and Java 8 gain widespread adoption.

share|improve this answer
    
thanks(+1). Your answer explains some of my doubts regarding how Scala would avoid it. Honestly, don't you think that once(if) Scala becomes atleast half as popular as Java at the enterprise level, armies of frameworks, patterns, paid app servers etc. would pop up? –  zencv Apr 16 at 13:05
    
I think if Scala were to overtake Java, it will be because people prefer the "Scala way" of architecting software. What strikes me as more likely is Java continuing to adopt more of the features that drive people to switch to Scala, like Java 5's generics and Java 8's lambdas and streams, which hopefully will eventually result in programmers abandoning anti-patterns that sprung up when those features weren't available. There will always be FactoryFactory adherents, no matter how good languages get. Obviously some people like those architectures, or they wouldn't be so common. –  Karl Bielefeldt Apr 16 at 20:52

In general, there is this trend that Java programs are horrendously over-engineered [citation needed]. Having many factories is one of the most common symptoms of over-engineering; that's why people make fun of those.

In particular, the problem Java has with factories is that in Java a) constructors are not functions and b) functions are not first-class citizens.

Imagine you could write something like this (let Function be a well-known interface of the JRE)

// Framework code
public Node buildTree(Function<BranchNode, Node, Node> branchNodeFactory) {
    Node current = nextNode();
    while (hasNextNode()) {
        current = branchNodeFactory.call(current, nextNode());
    }
    return current
}

// MyDataNode.java
public class MyBranchNode implements BranchNode {

    public MyBranchNode(Node left, Node right) { ... }
}

// Client code
Node root = buildTree(MyBranchNode::new);

See, no factory interfaces or classes. Many dynamic languages have first-class functions. Alas, this is not possible with Java 7 or earlier (implementing the same with factories is left as an exercise to the reader).

So, the alternative is not so much "use a different pattern", but more "use a language with a better object model" or "don't over-engineer simple problems".

share|improve this answer
2  
this doesn't even attempt to answer the question asked: "what are the alternatives?" –  gnat Apr 16 at 11:24
    
Read past the second paragraph and you will get to the "how other languages do it" part. (PS: the other answer also doesn't show alternatives) –  Arian Apr 16 at 11:31
4  
@gnat Isn't he indirectly saying the alternative is to use first-class functions? If what you want is a black box that can create objects, your options are either a factory or a function, and a factory's just a function in disguise. –  Doval Apr 16 at 11:33
3  
"In many dynamic languages" is a bit misleading, since what's actually needed is a language with first-class functions. "Dynamic" is orthogonal to this. –  Andres F. Apr 16 at 11:51
    
True, but it is a property often found in dynamic languages. I mentioned the need for first-class function in the beginning of my answer. –  Arian Apr 16 at 12:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.