aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Factory pattern(s) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Factory pattern(s)" Watch "Factory pattern(s)" New topic
Author

Factory pattern(s)

Ankit Doshi
Ranch Hand

Joined: Dec 04, 2002
Posts: 222
I am referring to the Java Design Patterns book from James Cooper. I think I have understood the Factory and the Abstract Factory patterns, but I have some doubts about the Factory Method pattern. This is what I have understood and what is not yet clear, please help me understand this better.

Factory: One seperate class, which, based on some criteria (evaluates some if else condition) instantiates one of the subclasses of a base class and returns to the client.

Abstract Factory: The methods in the Abstract Factory would return one of the concrete Factories, and the concrete Factories in turn, could be used to retrieve specific objects. So from higher perspective, Abstract Factory helps client to get family of related objects.

Factory Method: The book says that, it extends the idea of Factory pattern, but instead of having single class making decision as to which subclass to instantiate, the superclass would defer the decision to each subclass. I am not quite able to understand what does this mean. The example used in this book (if anyone is referring to this) also didn't help me to understand the concept.

I have also gone through some threads in the javaranch on similar topic, but not helpful so far.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
The Gang of Four book doesn't list Factory on its own, but Cooper is free to write up anything he likes. I happen to use something that matches that description frequently, so I'm happy to see it in your list.

Factory Method took me a while to get. (Ilja helped. ) Say I write an abstract class with an abstract method createNewWidget() that with an abstract Widget return type. If you want to extend that into a concrete class, you'll be required to implement createNewWidget and some concrete Widget. Some other extension of my abstract class might return a different concrete Widget. That's all there is to it.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Stan just outlined the idea of a Factory Method as presented by the Gang of Four and James Cooper.

However you will often run into the use of the term "Factory Method" where it refers to a much simpler construct as in Replace Constructor with Factory Method.
In this case it simply refers to a creational method that translates the input parameters to one of several concrete classes that is then returned as a representative of its super class or of an interface that it implements. So the create(type:int):Employee "Factory Method" will return an Employee that could actually be an Engineer, Manager, etc., based on the specified type. So in this case the decision is not deferred to each subclass but actually implemented right in the method.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I think that's what Cooper called Factory and GoF, um, apparently didn't think was worth mentioning. I've had great luck driving such things with keys and classnames in configuration so I can add new subtypes without touching the factory code. The factory can return singletons or not, too.
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Originally posted by Stan James:
I think that's what Cooper called Factory and GoF, um, apparently didn't think was worth mentioning.

According to the original post Cooper's Factory is an entire class. The "lesser" Factory Method doesn't necessarily belong to a Factory class, it could belong to any class. I would guess that GoF didn't think that the "lesser" Factory Method required an actual "pattern" designation because to them it was a creation idiom that is an integral part of polymorphism.
[ December 05, 2006: Message edited by: Peer Reynders ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
In "Refactoring to Patterns" that "lesser" pattern is actually called "Creation Method" to distinguish it from the more elaborate Factory Method pattern.

I just wished this distinction could win recognition...


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ankit Doshi
Ranch Hand

Joined: Dec 04, 2002
Posts: 222
Thanks all for the explanation.

It would be very helpful if you can please elaborate this further and help me clarify the below two points:

1.

Posted by Stan
I write an abstract class with an abstract method createNewWidget() that with an abstract Widget return type. If you want to extend that into a concrete class, you'll be required to implement createNewWidget and some concrete Widget. Some other extension of my abstract class might return a different concrete Widget. That's all there is to it.


I am not sure what purpose does this solve or what design problem it solves. What I understood from the above is that, Widget is the class whose instances needs to be created. The abstract class you create containing the abstract method createNewWidget is named say, WidgetCreator class. Now, if I am a client, how do I get instances of Widgets? I still need to know the WidgetCreator abstract class and it's concrete subclasses in order to get either the Widget class or one of it's subclasses. Means the client is still locking to one of the WidgetCreator classes, which is Factory Method class.


2. As far as the 'design problem that a particular pattern solves' is concerned, I am a bit confused about the Factory and the Abstract Factory as well. In the earlier times when I was not aware of the design patterns, I had used following type of code for dynamically instanting one of the subclasses:

Let say I have a interface Protocol and I have two concrete classes say, ProtocolX and ProtocolY implementing the Protocol interface. Below is the client code which needs instances of one of the concrete Protocol implementations.

Client Code:
Object obj = Class.forName ( property.getProperty( ProtocolName + ".ClassName") );
Protocol p = (Protocol)obj.newInstance();

Here I was passing the name of the protocol in the ProtocolName variable dynamically and my property file was like this:
ProtocolX.ClassName=mypackage.ProtocolX
ProtocolY.ClassName=mypackage.ProtocolY

This used to work fine with me. What I am not able to imagine at this point, is the scenario in which the Factory OR Factory Method OR Abstract Factory pattern can be useful, while the above approach (using property file) would NOT be useful.
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
This used to work fine with me. What I am not able to imagine at this point, is the scenario in which the Factory OR Factory Method OR Abstract Factory pattern can be useful, while the above approach (using property file) would NOT be useful.

I don't think the two approaches are really conflicting choices. They are potentially different "levels" of the same solution.

The point of using a factory method (for example) is that it decouples the user of the created objects from the code used to create it. That way a developer is free to change the way creation is implemented (perhaps by cacheing created objects, or using a "prototype and clone" technique rather than the "class and new instance" approach you describe) without affecting client code.

Imagine the client code looks something like:


We can make this work by using your technique, above:



Or we could (for example) get more fancy and do something like:



Without needing to modify the client code.

This is a common benefit of a lot of patterns: providing clean lines of separation between different responsibilities in the code, so that chaging one does not always imply changing the other.

Does that make any sense?


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
Ankit Doshi
Ranch Hand

Joined: Dec 04, 2002
Posts: 222
Ok, I got your point about caching. With the code I used, it would not be possible to have any caching.

But, the example you gave above - is that the example of the Factory Method or of Factory?

I thought:
- In Factory pattern, there is a seperate Factory class that takes care of object creation (based on some if else condition, or may be even using the property files as above)
- And in Factory Method pattern, there is one abstract method (known as factory method) which takes care of the object creation, and may be this method is part of the client code (not sure about this though).

Also, could you please point out one practical example where Factory pattern can be preferred over the other and same way a practical example where the Factory Method can be preferred over the other?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Stan's example is an Abstract Factory, which basically is a polymorphic version of what you seem to call the Factory pattern.

It simply is more flexible than the Class.forName approach. Caching is just one example - think about instanciating a class without a default constructor, or based on some database content, based on parameters given to factory when initialized etc. pp.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ankit Doshi:
in Factory Method pattern, there is one abstract method (known as factory method) which takes care of the object creation, and may be this method is part of the client code (not sure about this though).


In the Factory Method pattern, the superclass is the client of a method that it defines as abstract, and which is implemented in subclasses.

Think of Factory Method as a special case of Template Method (whereas Abstract Factory is more like the Strategy pattern).
Ankit Doshi
Ranch Hand

Joined: Dec 04, 2002
Posts: 222
Originally posted by Ilja Preuss:


In the Factory Method pattern, the superclass is the client of a method that it defines as abstract, and which is implemented in subclasses.


Let's assume
- Product is the name of the class whose instances are needed
- ProductClient is the name of the client program which needs above instances
- getProduct() is the name of the abstract method which will be the factory method.

The question is - the getProduct() method will be part of which class? Part of ProductClient class? Or there's a seperate factory class like ProductFactory which contains the abstract getProduct() method?
Ankit Doshi
Ranch Hand

Joined: Dec 04, 2002
Posts: 222
The above question is in context of the "Factory Method" pattern.
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Originally posted by Ankit Doshi:
In Factory pattern, there is a separate Factory class that takes care of object creation (based on some if else condition, or may be even using the property files as above)


There really isn't a "Factory Pattern" as such. There is the "Abstract Factory Pattern" and the "Factory Method Pattern". Sometimes people will say "Factory Pattern" and mean "Abstract Factory Pattern". I suspect that in James Cooper's case the "Factory Pattern" is an intermediate concept where the Abstract Factory and Concrete Factory classes of the "Abstract Factory Pattern" are collapsed into one single class - maybe in the spirit of "creational method" the "James Cooper Factory Pattern" should be called "creational class".

However once you end up with a whole mess of "if-then-else conditions" inside your creational class you should be compelled to apply the Replace Conditional with Polymorphism refactoring which will lead you towards the Abstract Factory anyway.
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
You really haven't supplied enough information to make an informed decision
  • Its unlikely that the getProduct() Method would be part of the ProductClient class. To leverage Polymorphism and the LSP (Liskov Substitution Principle) you want to keep the ProductClient oblivious to the differences in the specific Products - the specific Products themselves are supposed to manage the differences. So ultimately the ProductClient should be the Client of the "getProduct()" method, not the Server.
  • If you simply have a DB lookup that creates a specific product based on a product code then all you need is a creational method on a DAO or any other DB Access object.
  • If your company deals with both Fresh and Frozen products it may wish deal with the Orders separately because of the different storage, shipping and handling requirements. However the ProductClient may need to work with both - just not at the same time. The ProductClient would be coded against a general, abstract ProductServer class. Before an Order is started the client must specify whether this is a "Fresh" or "Frozen" order - then it gets handed a ProductServer object (this can be handled via a getProductServer(productType:string):ProductServer creational method) which actually is either a FreshProductServer or FrozenProductServer object. Then ProductServer.getProduct() is the abstract method while FreshProductServer.getProduct() and FrozenProductServer.getProduct() are the concrete methods. Here the getProduct() method is a Factory Method. ProductServer is not yet an Abstract Factory at this point as it only serves objects from one single inheritance hierarchy (or which implement one particular interface) - Product. In the Abstract Factory Pattern objects from multiple related inheritance hierarchies (or interfaces) are served.

  • Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Ankit Doshi:


    Let's assume
    - Product is the name of the class whose instances are needed
    - ProductClient is the name of the client program which needs above instances
    - getProduct() is the name of the abstract method which will be the factory method.

    The question is - the getProduct() method will be part of which class? Part of ProductClient class? Or there's a seperate factory class like ProductFactory which contains the abstract getProduct() method?


    If you have a ProductFactory class, you have a "creation class".

    If the ProductFactory is abstract and the getProduct method implemented by different subclasses, you have an Abstract Factory.

    If the getProduct method is declared abstract inside ProductClient, and implemented by its subclasses (without having a ProductFactory class at all), its a Factory Method.

    Does that help?
    Ankit Doshi
    Ranch Hand

    Joined: Dec 04, 2002
    Posts: 222
    Originally posted by Ilja Preuss:


    If you have a ProductFactory class, you have a "creation class".

    If the ProductFactory is abstract and the getProduct method implemented by different subclasses, you have an Abstract Factory.

    If the getProduct method is declared abstract inside ProductClient, and implemented by its subclasses (without having a ProductFactory class at all), its a Factory Method.



    Yes, this helps clarify the differences. Thanks.
    Peer Reynders
    Bartender

    Joined: Aug 19, 2005
    Posts: 2922
        
        5
    Originally posted by Ilja Preuss:
    If the ProductFactory is abstract and the getProduct method implemented by different subclasses, you have an Abstract Factory.


    I know I'm nitpicking...
    but don't you need to create "a family of related product objects is designed to be used together" before your can call yourself an Abstract Factory (in the canonical form that is)?

    BTW: Head First Design Patterns calls the creational class a "Simple Factory" and gives it honourable mention as an idiom, rather than a pattern. An idiom is usually a low-level pattern that is common for a given programming langauge but I guess in this context it could be an idiom for for all programming languages that support polymorphism. But regardless, everybody seems to be using their own name for this common idiom which doesn't help communication.
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Peer Reynders:

    I know I'm nitpicking...
    but don't you need to create "a family of related product objects is designed to be used together" before your can call yourself an Abstract Factory (in the canonical form that is)?


    If you go by the letter, probably. I don't see how that distinction would be helpful, though.

    Perhaps we could simply agree that we can have families with just one member? (Did I mention that I studied mathematics for a while? )
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Factory pattern(s)