Reputation: 34424
What is Abstract Factory Pattern :-
It provides a way where a top level factory encapsulate a group of individual factories that are further able to create the family of related products without specifying their concrete classes.
As per Examples of GoF Design Patterns in Java's core libraries below is cited as example of Abstract pattern
javax.xml.parsers.DocumentBuilderFactory#newInstance()
But i am not sure how come its following the Abstract Factory Pattern here.
Is DocumentBuilderFactory
considered as top level factory which internally
cotains individual factory i.e DocumentBuilderFactory#newInstance()
which is able to create the family of related products without specifying their concrete classes (as it just return the DocumentBuilderFactory
not any specific implementation). Is this correct?
Upvotes: 3
Views: 12480
Reputation: 77910
Reference
What is a factory pattern?
A Factory method pattern (aka Factory pattern) is a creational pattern. The creational patterns abstract the object instantiation process by hiding how the objects are created and make the system independent of the object creation process.
An Abstract factory pattern is one level of abstraction higher than a factory method pattern which means it returns the factory classes.
Const
public interface Const {
public static final int SHAPE_CIRCLE =1;
public static final int SHAPE_SQUARE =2;
public static final int SHAPE_HEXAGON =3;
}
ShapeFactory
public abstract class ShapeFactory {
public abstract Shape getShape(int shapeId);
}
In addition to SimpleShapeFactory
we create new one:
ComplexShapeFactory
public class ComplexShapeFactory extends ShapeFactory {
public Shape getShape(int shapeTypeId){
Shape shape = null;
if(shapeTypeId == Const.SHAPE_HEXAGON) {
shape = new Hexagon();//complex shape
}
else{
// drop an error
};
return shape;
}
}
Now let’s create at the abstract factory, which returns one of the types of ShapeFactory
:
ShapeFactoryType
public class ShapeFactoryType {
public static final int TYPE_SIMPLE = 1;
public static final int TYPE_COMPLEX = 2;
public ShapeFactory getShapeFactory(int type) {
ShapeFactory sf = null;
if(type == TYPE_SIMPLE) {
sf = new SimpleShapeFactory();
}
else if (type == TYPE_COMPLEX) {
sf = new ComplexShapeFactory();
}
else throw new BadShapeFactoryException("No factory!!");
return sf;
}
}
And now the main call:
ShapeFactoryType abFac = new ShapeFactoryType();
ShapeFactory factory = null;
Shape s = null;
//returns a ShapeFactory but whether it is a
//SimpleShapeFactory or a ComplexShapeFactory is not known to the caller.
factory = abFac.getShapeFactory(1);//returns SimpleShapeFactory
//returns a Shape but whether it is a Circle or a Pentagon is
//not known to the caller.
s = factory.getShape(2); //returns square.
s.draw(); //draws a square
//returns a ShapeFactory but whether it is a
//SimpleShapeFactory or a ComplexShapeFactory is not
//known to the caller.
factory = abFac.getShapeFactory(2);
//returns a Shape but whether it is a Circle or a Pentagon is
//not known to the caller.
s = factory.getShape(3); //returns a pentagon.
s.draw(); //draws a pentagon
The DocumentBuilderFactory
is like ShapeFactoryType
in example.
The newInstance(String factoryClassName,ClassLoader classLoader)
returns new instance of a DocumentBuilderFactory
based on factoryClassName
(in my case I used abFac.getShapeFactory(1);
and abFac.getShapeFactory(2);
).
Upvotes: 4
Reputation: 42040
The default implementation included in the JDK is com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
, but there are several implementations (factories). e.g.:
com.google.gdata.util.common.xml.parsing.SecureGenericXMLFactory
com.icl.saxon.om.DocumentBuilderFactoryImpl
com.meterware.httpunit.dom.DocumentBuilderFactoryFilter
com.sun.msv.verifier.jaxp.DocumentBuilderFactoryImpl
net.sf.saxon.dom.DocumentBuilderFactoryImpl
org.allcolor.xml.parser.CDocumentBuilderFactory
...
In order to get the implementation to use (with the method newInstance()
), in the javadoc of javax.xml.parsers.DocumentBuilderFactory
you can read:
Obtain a new instance of a
DocumentBuilderFactory
. This static method creates a new factory instance. This method uses the following ordered lookup procedure to determine theDocumentBuilderFactory
implementation class to load:
- Use the
javax.xml.parsers.DocumentBuilderFactory
system property.- Use the properties file
"lib/jaxp.properties"
in the JRE directory. This configuration file is in standard java.util.Properties format and contains the fully qualified name of the implementation class with the key being the system property defined above. Thejaxp.properties
file is read only once by the JAXP implementation and it's values are then cached for future use. If the file does not exist when the first attempt is made to read from it, no further attempts are made to check for its existence. It is not possible to change the value of any property injaxp.properties
after it has been read for the first time.- Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for a classname in the file
META-INF/services/javax.xml.parsers.DocumentBuilderFactory
in jars available to the runtime.- Platform default
DocumentBuilderFactory
instance.Once an application has obtained a reference to a
DocumentBuilderFactory
it can use the factory to configure and obtain parser instances.
Upvotes: 1
Reputation: 2712
DocumentBuilderFactory#newInstance()
gives you a DocumentBuilder
, which is a factory for Document
s.
So DocumentBuilderFactory
is a factory that produces factories, or in other words, an abstract factory. This is required because there are many implementations of DocumentBuilder
depending on JDK version and installed libraries.
Does that clear it up?
Upvotes: 1