Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I implementing a generics-based Java factory correctly?

I don't believe I am implementing the factory pattern correctly because the Application class' createDocument method accepts any class type, not just subclasses of Document.

In other words, is there a way I can restrict the createDocument method to only accept subclasses of Document?

  • Document.java

    package com.example.factory;
    
    public abstract class Document {
        public Document() {
            System.out.println("New Document instance created: " + this.toString());
        }
    }
    
  • DrawingDocument.java

    package com.example.factory
    
    public class DrawingDocument extends Document {
        public DrawingDocument() {
            System.out.println("New DrawingDocument instance created: " this.toString());
        }
    }
    
  • Application.java

    package com.example.factory;
    
    public class Application {
        public <T> T createDocument(Class<T> documentClass) {
            try {
                return documentClass.newInstance();
            } catch (InstantiationException e) {
                throw new IllegalArgumentException(e);
            } catch (IllegalAccessException e) {
                throw new IllegalArgumentException(e);
            }
        };
    }
    
  • Main.java

    package com.example.factory;
    
    public static void main(String[] args) {
        Application application = new Application();
        application.createDocument(DrawingDocument.class);
    }
    
like image 936
Andrew Avatar asked May 31 '11 18:05

Andrew


People also ask

Why would you use generics in java?

Generics enable the use of stronger type-checking, the elimination of casts, and the ability to develop generic algorithms. Without generics, many of the features that we use in Java today would not be possible.

How does java generic work?

In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.

What is java Factory?

Factory method is a creational design pattern which solves the problem of creating product objects without specifying their concrete classes. The Factory Method defines a method, which should be used for creating objects instead of using a direct constructor call ( new operator).


2 Answers

You should bound your generic so that it is only using T's that inherit Document. example:

public class Application {
    //Add extends Document after T
    public static <T extends Document> T createDocument(Class<T> documentClass) throws InstantiationException, IllegalAccessException {
        return documentClass.newInstance();
    };
}
like image 161
Yet Another Geek Avatar answered Oct 13 '22 23:10

Yet Another Geek


The code looks good. In a real implementation the factory method should not be declared to throw any of the reflection-related exceptions. And you will probably have some different code anyway to create the document.

The faxtory method should take a Class<? extends Document> as its parameter, so that one cannot ask it to create a String, for example.

[update:] Code sample:

public Document createDocument(Class<? extends Document> clazz) {
  try {
    return clazz.newInstance();
  } catch (InstantiationException e) {
    throw new IllegalArgumentException(e);
  }
}
like image 22
Roland Illig Avatar answered Oct 13 '22 22:10

Roland Illig