1
\$\begingroup\$

I started learning factory pattern, and also implemented factory method pattern.

My factory-method pattern classes are as follows:

  1. There are two major parts, an interface "Document.java" and and abstract class DocumentCreator.java which has an abstract method createDocument.
  2. Classes XMLDocumentCreator and ExcelDocumentCreator are subclasses of DocumentCreator.
  3. Classes XMLDoc and ExcelDoc both are implementing Document interface.

Interface Document.java

public interface Document { 
  String parse(String parser);
}

Classes implementing above interface

public class XMLDoc implements Document{

  @Override
  public String parse(String parser) {      
    return "This XML document can be parsed by \""+parser+"\" parser";
  }

}


public class ExcelDoc implements Document{

  @Override
  public String parse(String parser) {      
    return "This Excel document can be parsed by \""+parser+"\" parser";
  }

}

Abstract class DocumentCreator.java is as follows:

public abstract class DocumentCreator {
  public abstract Document createDocument();
}

Classes extending the above class is:

public class ExcelDocumentCreator extends DocumentCreator{

  @Override
  public Document createDocument() {        
    return new ExcelDoc();
  }

}

public class XMLDocumentCreator extends DocumentCreator{


  @Override
  public Document createDocument() {        
    return new XMLDoc();
  }

}

This is my MainClass.java from where I run the application:

public class MainClass {
  public static void main(String [] args){
    DocumentCreator docCreator = new XMLDocumentCreator();
    System.out.println(docCreator.createDocument().parse("SAX"));
    System.out.println(docCreator.createDocument().parse("DOM"));

    docCreator = new ExcelDocumentCreator();
    System.out.println(docCreator.createDocument().parse("MSDoc"));
    System.out.println(docCreator.createDocument().parse("OpenOffice"));
  }
}

When I run the class, I get:

This XML document can be parsed by "SAX" parser
This XML document can be parsed by "DOM" parser
This Excel document can be parsed by "MSDoc" parser
This Excel document can be parsed by "OpenOffice" parser

Now, after looking at my class hierarchy, is the implementation a proper usage of factory-method pattern? Is the "DocumentCreator creates document" problem solved properly by the pattern? Can you please give me any suggestions like where the factory-method pattern can be applied?

\$\endgroup\$
1
\$\begingroup\$

Although your implementation is superficially correct, my guess is that it is missing some of the finer points of factory method implementation .

A good example that you can look at is URLStreamHandlerFactory in java.

Some minor changes that I would make to your code would be to Introduce an Enum such as

public enum TYPE {
    EXCEL,
    XML

}

Modify my DocumentCreator to

public abstract class DocumentCreator {
    public static Document createDocument(TYPE type) {

        if (type.equals(TYPE.EXCEL)) {
            return new ExcelDoc();
        } else if (type.equals(TYPE.XML)) {
            return new XMLDoc();
        } else {
            // Default Implementation
            return new XMLDoc();
        }

    }

    public static Document createDocument() {

        return new XMLDoc();

    }
}

And my main Class would invoke as follows :

public class MainClass {

    public static void main(String [] args){
       // DocumentCreator docCreator = new XMLDocumentCreator();
        System.out.println(DocumentCreator.createDocument().parse("SOMETHING"));
        System.out.println(DocumentCreator.createDocument(TYPE.XML).parse("SAX"));
        System.out.println(DocumentCreator.createDocument(TYPE.EXCEL).parse("DOM"));
        System.out.println(DocumentCreator.createDocument(TYPE.XML).parse("MSDoc"));
        System.out.println(DocumentCreator.createDocument(TYPE.EXCEL).parse("OpenOffice"));


      }
}

These are just a few minor modifications to your code . I would suggest you to go though this Factory Pattern Explained to understand the finer aspects of 1) Instantiation control 2) loose coupling 3) improving readability by encapsulation which is feel is the primary need of using the factory pattern.

\$\endgroup\$
2
  • \$\begingroup\$ My guess is that returning an XMLDoc as default in DocumentCreator is a bad habit. You should instead trhow an exception explaining that TYPE is not known/supported/managed/authorized.. \$\endgroup\$
    – gervais.b
    Sep 16 '16 at 6:15
  • \$\begingroup\$ I'm not sure about this one. The if/else list in createDocument(TYPE type) is not as easily modified as the solution in the question. Hard coding all existing types into a single DocumentCreator does not seem to be very flexible. I actually prefer the approach in the question that's based on multiple classes and polymorphism. I think it is more loosely coupled and each document type is better encapsulated in its own pair of factory and product classes. \$\endgroup\$ Sep 16 '16 at 19:33
0
\$\begingroup\$

You have a lot of structure without any benefit as already recognized in some comments.

Because you have to decide what to create with your "Type" enum it is as worth as instantiating the concrete documents directly.

You really will have a benefitial factory if it is able to decide to create the correct concrete "Document" from the input string.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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