jtstuar94 jtstuar94 - 1 month ago 4x
Java Question

JDK DOM Parser: Why Factories?

I'm currently going over XML parsing using the JDK's standard DOM parser.

However, I figured that this would be a good time to understand what the point of the Factory pattern is. I tried finding examples of Factory's utility before, and many explanations attempt to use an example like:

"If a user inputs 'Dog' as a String we can use an AnimalFactory to recognize 'Dog' and instantiate the corresponding object, which is useful if we don't know what we need at runtime."

These kinds of examples don't really drive the point home for me though (perhaps due to my overlooking something) and I feel that understanding why Factory is implemented in the JDK's standard DOM parser would really help me (and hopefully others) out. So here it is:

I've read that reading in an XML document requires the instantiation of a DocumentBuilder object— which can only by retrieved from a DocumentBuilderFactory object as so:

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

which now enables us to pass a File object to it like this:

File myFile = Paths.get(fooPath).toFile();

But, why does process merit a Factory pattern? Why is the above approach better than DocumentBuilder having its own explicit constructor and passing the file in the same way?

In this case, is it just a question of organizing constructors for objects with similar purposes?

Thanks in advance.


The DocumentBuilderFactory.newInstance() will return One of Two implementations either:

  1. a "javax.xml.parsers.DocumentBuilderFactory"

or if that doesn't exist

  1. a "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl".

I'm not 100% sure - but in this specific case - it looks like it wants to give you a newer implementation of DocumentBuilderFactory (that comes with the JRE). If its not there you get the old one.

The power of the Factory pattern is it will return something that can be used with out the coder (you) worrying about the implementation. If its from the java.xml.parsers package or the old com.sun.org.apache.xerces.internal.jaxp package we know that what we get back can be used in the same way. In the future, if a new XML parser is created (maybe its faster) and they decide to replace the one in javax.xml, it doesn't matter to the coder using the API - it will "just work". They will benefit from the new code (if its there) or they will use one of the previous implementations.

A Factory is a "creational pattern". You can return several types of object that can all be acted upon (by the programmer) in the same way.

When you are coding and you find yourself doing a lot of:

MyObject genericObject = null;

if mySetting.equals("dog") {
    genericObject  = new Dog();
} else if { mySetting.equals("cat") {
    genericObject  = new Cat();

You will save time by having a factory create the proper object. If you introduce a Snake() then you only have to update the creational code in one place.

The pattern is often used to create objects that have the same contract (Interface) so it often helps with Polymorphism

If something is not clear let me know and I will update my answer.

Here is a chapter on it from my favorite Design Patterns book: Head First Design Patterns