Gang of Four Creational pattern: Prototype
A fully initialized instance to be copied or cloned. Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
The prototype factory pattern uses a map of pre-initialized instances where there is one of each type in the map.
When an instance of a certain type is requested the relevant instance is retrieved and cloned.
This pattern is typically used where expensive initialisation in the constructor is present so it is cheaper to clone the class than do an expensive initialisation every time a new instance is required.
To get the code for this example:
git clone https://github.com/spotadev/gangoffour.git
In src/main/java navigate to this package:
com.javaspeak.designpatterns.go4.creational.prototype
You can run the code from the main method of:
PrototypeApplication
In this example there is a map of different shapes in the PrototypeFactory
When a Shape such as a Square is requested using the getShape() method, the appropriate instance is retrieved from the map and cloned.
package com.javaspeak.designpatterns.go4.creational.prototype;
/**
* Text book description:
* <ul>
* "Prototype: A fully initialized instance to be copied or cloned. Specify the kinds of
* objects to create using a prototypical instance, and create new objects by copying this
* prototype. "
* </ul>
* The prototype factory pattern uses a map of pre-initialized instances where there is one of
* each type in the map.
* <p>
* When an instance of a certain type is requested the relevant instance is retrieved and cloned.
* <p>
* This pattern is typically used where expensive initialisation in the constructor is present
* so it is cheaper to clone the class than do an expensive initialisation every time a new
* instance is required.
* <p>
* In this example there is a map of different shapes in the PrototypeFactory
* <p>
* When a Shape such as a Square is requested using the getShape() method, the appropriate instance
* is retrieved from the map and cloned.
*
* @author John Dickerson - 22 Feb 2020
*/
public class PrototypeApplication {
/**
* Retrieves a cloned copy of the required Shape from the Prototype Factory
*
* @throws CloneNotSupportedException
*/
public void draw() throws CloneNotSupportedException {
ProtypeFactory.getShape( ShapeType.SQUARE ).draw();
ProtypeFactory.getShape( ShapeType.TRIANGLE ).draw();
}
public static void main( String[] args ) throws CloneNotSupportedException {
PrototypeApplication application = new PrototypeApplication();
application.draw();
}
}
package com.javaspeak.designpatterns.go4.creational.prototype;
import java.util.EnumMap;
import java.util.Map;
/**
* @author John Dickerson - 24 Feb 2020
*/
public class ProtypeFactory {
private static Map<ShapeType, Shape> shapeCache =
new EnumMap<ShapeType, Shape>( ShapeType.class );
static {
shapeCache.put( ShapeType.SQUARE, new Square() );
shapeCache.put( ShapeType.TRIANGLE, new Triangle() );
}
/**
* Retrieves a Shape from the map and clones it
*
* @param shapeType
he kind of Shape to retrieve
* @return the Shape
*
* @throws CloneNotSupportedException
* Thrown if the the Shape does not implement Cloneable
*/
public static Shape getShape( ShapeType shapeType )
throws CloneNotSupportedException {
return ( Shape )shapeCache.get( shapeType ).clone();
}
}
package com.javaspeak.designpatterns.go4.creational.prototype;
/**
* Abstract class which provides clone functionality and drawing functionality for a Shape.
*
* @author John Dickerson - 24 Feb 2020
*/
public class Shape implements Cloneable {
protected String pixels;
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Draws the pixel representation of the Shape
*/
public void draw() {
System.out.println( pixels );
}
}
package com.javaspeak.designpatterns.go4.creational.prototype;
/**
* Enum showing the different types of Shapes
*
* @author John Dickerson - 24 Feb 2020
*/
public enum ShapeType {
SQUARE, TRIANGLE;
}
package com.javaspeak.designpatterns.go4.creational.prototype;
/**
* @author John Dickerson - 24 Feb 2020
*/
public class Square extends Shape {
/**
* Constructor pretending to do some expensive initialisation
*/
public Square() {
StringBuilder sb = new StringBuilder();
sb.append( "xxxxxxx\n" );
sb.append( "x x\n" );
sb.append( "x x\n" );
sb.append( "xxxxxxx\n" );
this.pixels = sb.toString();
}
}
package com.javaspeak.designpatterns.go4.creational.prototype;
/**
* Triangle
*
* @author John Dickerson - 24 Feb 2020
*/
public class Triangle extends Shape {
/**
* Constructor pretending to do some expensive initialisation
*/
public Triangle() {
StringBuilder sb = new StringBuilder();
sb.append( " x \n" );
sb.append( " x x \n" );
sb.append( " x x \n" );
sb.append( "xxxxxxx\n" );
this.pixels = sb.toString();
}
}
Back: Gang of Four
Page Author: JD