Collaborator vs. the Factory

March 30th, 2009 · 11 Comments ·

by Miško Hevery

I have already hinted that your code should either be in the business of doing business logic or in the business of instantiating and wiring other objects together. What this effectively means is that your either have classes with ifs and loops (your business logic) or you have classes with new operators (your factories). Now at this point many people assume that they will need a factory for each class which will double the number of classes. But in practice you only need one factory class each time you cross an object lifetime. For example most web application, this implies that you have a factory for the application lifetime objects and than a factory for all af the request lifetime objects. More specifically one request lifetime factory for each servlet we have, since a servlet is long lived and we need a request lived object (we are crossing the boundary). Let’s look at an example of a LoginServlet.

collaborator-vs-factory

The problem with the LoginServlet is that it is of wrong lifetime. A servlet is application lifetime object or a singleton. This means that we can not store any request level information in the servlet. Most people solve this problem by passing all of the request lifetime information through the stack to all of the different methods. However I thing that the responsibility of the servlet is to create a request lifetime object graph and than pass the execution to it. By creating a request scope object graph we are free to store the data in the class fields rather than being forced to pass them around on the stack. The responsibility of the LoginServlet is to create a LoginPage, it is a factory.

To allow the removal of the new operators from our business logic classes, we need to ask for our collaborators instead of making them. This means that each class only knows about other classes with which it is in direct contact and which it needs to get its job done. In our example the LoginPage would ask for AuditRecord and Authenticator in its constructor. Similarly the Auhenticator class would ask for Database, Captcha and AuditRecord as its collaborators. Finally the Database would ask for AuditRecord.

But how do we get the right information to the right location, or to put it differently, how do I get information to the database object without the Authenticator knowing, since the Authenticator is in the middle? The trick lies that the view of the world from the factory is different than the view from the collaborator.

Each collaborator only knows about its direct dependencies, as depicted by the arrow pointing to the right. And that is a good thing since it makes code reusable and it prevents any one class from knowing too much.

Now, let’s look at the factory. When the factory calls a new on the Login Page it must satisfy two dependencies: AuditRecord and the Authenticator. To make an Authenticator we must first instantiate a Database, Captcha and AuditRecord. However, we need to make sure that the AuditRecord in the Authenticator and in LoginPage is same instance, so we simply reuse it. Here is how it looks like in the code form:

AuditRecord audit = new AuditRecord();
Database database = new Database(audit);
Captcha captcha = new Captcha();
Authenticator authenticator =
    new Authenticator(database, captcha, audit);
LoginPage = new LoginPage(audit, authenticator);

What I find interesting is how different the code looks from the two points of view. The collaborators only know about its direct dependecies and the factories know about everything, and that is a good thing. Because the factories know about all of the objects in the graph they can easily make sure that everyone gets the same instance of the AuditRecord. In other words the factory can easily enforce that AuditRecord is a singleton without having to rely on a global variable. It also means that the factory can deliver the information to any one object without anyone else knowing about the information unnecessarily. For example if the AuditRecord needs to know the the HTTP cookie than the factory can inject the cookie into the AuditRecord without effecting any of the layers in between, namely the Authenticator and Database.

Tags: Uncategorized

11 responses so far ↓

  • Oleg // Mar 31, 2009 at 5:09 am

    Hi, Misko.I would like to see a larger (working) piece of code or a project, designed using principles you describe on this blog. I really want to “feel” such code under my fingertips ;-) Could you point me to some?Thanks.Oleg

  • Edd Grant // Mar 31, 2009 at 5:42 am

    I like your thinking here, presumably the objects that the servlet uses in it’s guise as a factory could even be provided via dependency injection where appropriate.One thought, I wonder if it would beneficial to still write separate servlet and factory classes in order to provide cleaner separation from a testing point of view? I’d imagine that doing this would effectively draw a line between the servlet and factory classes, ensuring that any servlet specific ties or test setup requirements would not be present when testing the factory class? Any thoughts on this?

  • Ionut G. Stan // Mar 31, 2009 at 7:43 am

    Great post Misko. I’ve recently discovered your blog and I must say I’m very glad about it. I have one question though (as anyone else)…In your example, the factory is lucky enough to know everything is needed for the call graph. But in my experience I saw there are times when objects are created based on business logic. So, some object requires a certain object, with a certain interface. The tricky part is that the concrete object  type is determined at runtime in some business logic code.What should I do in this case?I’m trying my luck with a little idea, maybe I’m on the right track.I for one, would create yet another factory, which takes as an argument the result of the business logic processing and decides which object to return. This factory already has a pool of object from which to return the appropriate object based on the passed argument. The pool would be created in the main factory (concrete objects passed as arguments to the factory). My factory would then be passed as an argument to the appropriate object in the same main factory.Is that OK? Does it have shortcomings?I remember you said factories should not present logic, whereas this one does have at least a switch structure (in Java).

  • misko // Mar 31, 2009 at 7:49 am

    @Ionut,

    I think you are on the right track. Sometimes a factory needs to insatiate different things depending on some arguments. This is the only time when I will say that trivial if statements are probably ok. But in general you are right. Let the factory control the wiring process keeping the ifs out of it (as much as possible).

  • German // Apr 5, 2009 at 11:02 am

    May I humbly request that you don’t write “than” when you mean “then”? Sorry about that. The blog is great and I think every Java developer should give it a good read. 

  • igorbrejc.net » Fresh Catch For April 8th // Apr 7, 2009 at 11:04 pm

    [...] Collaborator vs. the Factory [...]

  • Zen // May 8, 2009 at 11:45 am

    @Ionut, Misko
    First Misko, thanks for a more than excellent blog. I came about it today, and I can’t stop reading. I’ve learned a great lot.

    To the problem with factory logic. You could avoid it by creating multiple get methods. Couldn’t you?

    An example:

    Connection con
    if (something is true) then
    con = Factory.getDatabaseConnection()
    else
    con = Factory.getFileBasedConnection()
    End if

    Misko, (and you other experts), would you consider the above be a better way of doing things than the next example below?

    Example 2:

    Connection con
    if (something is true) then
    con = Factory.getConnection(‘Database’)
    else
    con = Factory.getConnection(‘File’)
    End if

  • misko // May 9, 2009 at 9:29 pm

    @Zen,

    Thanks for posting, but I don’t think I understand your question or what you think are the differences between your two example or how it solves the if in factory problem. Could you explain your view in more detail.

  • EIP Special Report: DDD Is All Around « I Built His Cage // Jun 3, 2009 at 6:45 pm

    [...] a domain layer, and a UI layer. Components are injected everywhere (homemade DI). Factories are the only classes that instantiate classes. And the result is some of the most beautiful code I’ve ever written, and I doubt it took any [...]

  • JW // Feb 2, 2011 at 3:16 pm

    Thanks for an interesting article. But I’m still a little confused about how you avoid the need for lots of factories.

    The objects in your example all seem to be at the request level — e.g. you only need one Database instance per request.

    But how do you handle objects that need to be created dynamically? Maybe you need to pass arguments to their constructors that aren’t available until runtime. Or you need to create multiple instances of them.

    It seems like in these cases, where object X needs to create instances of object Y, you’d need to give X a YFactory. And if you need to create instances of X, you might need an XFactory, and so on. Wouldn’t you still end up with a factory for most classes?

  • misko // Feb 3, 2011 at 2:05 pm

    @JW,

    if you are using DI framework, than most of these factories will be implied, and you don’t need to write them. If you are doing it by hand, than you will need these factories, but a single factory can be responsible for a whole object graph, so there is not necessarily a one-to-one correspondence there between classes and factories.

Leave a Comment