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开发者_StackOverflow社区 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); }
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();
};
}
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);
}
}
Where is the restriction to Document type in the factory ? Try
public <T extends Document> T createDocument(Class<T> documentClass) throws InstantiationException, IllegalAccessException {
return documentClass.newInstance();
};
精彩评论