Using the Prototype Design Pattern In Java
Join the DZone community and get the full member experience.
Join For FreeLet's discuss today another creational design pattern named - Prototype Design Pattern.
Prototype Design Pattern
- The Prototype Design Pattern is one of the twenty-three well-known GoF design patterns which helps us copying an existing object rather than creating a new instance from scratch.
- The Prototype pattern is used when we need to create a number of instances of a class and each instance has almost same state or has very little difference.
- The Prototype pattern is used when creation of actual object directly is costly as per resource and data it holds and also is a time taking.
- The existing original object acts as a prototype and contains the state of the object. The new object is copy of the original object.
- The Prototype pattern is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.
- We are free to change values in the newly copied object whenever we required.
- The Prototype pattern helps us to save costly resources and time, especially when the object creation is a heavy and time taking process.
- In Java, One of the best available way to create object from existing objects are by using clone() method of Cloneable interface. Clone is the simplest approach to implement prototype pattern.
- We can also implement Prototype interface by using Deep Copy method.
- Deep Copy - By Deep copy we create an object by copying all the fields of the original object. And also if the original object contains other objects as fields, we copy them as well.
- Shallow Copy - By Shallow copy we create an object by copying all the fields of the original object. But if the original object contains other objects as fields, we copy only the reference of those objects instead of copying complete object itself.
- There are two ways of implementing the Prototype pattern
- Basic Implementation
- Prototype Registry Implementation
Basic Implementation
Prototype Registry Implementation
- In the Prototype Registry implementation of the pattern, we create a registry class to cache the objects for prototyping. In other worlds we use a prototype collection and management service or class which makes all the prototype accessible and available for prototyping.
- The purpose of the cache-registry is to maintain a pool of prototype ready objects in-memory.
To better understand this, let's look at an example of geometric shapes. I am keeping the example relatively simple to keep the focus on the pattern.
Let's first define few common enums which we will use in each of different methods on implementation of Prototype pattern.
Here, the code for Color enum:
package org.trishinfotech.prototype;
public enum Color {
RED, GREEN, BLUE, YELLOW, WHITE, BLACK, ORANGE, MAROON
}
Here, the code for LinePattern enum. We will use these line patterns for drawing different geometric shapes.
xxxxxxxxxx
package org.trishinfotech.prototype;
public enum LinePattern {
SOLID, DASH, DOT, DOUBLE_DASH, DASH_SPACE
}
Here, the code for FillPattern enum. We will use these fill patterns for painting different geometric shapes.
xxxxxxxxxx
package org.trishinfotech.prototype;
public enum FillPattern {
SOLID, DASH, DOT, CHECKS, HEART;
}
Geometric Shapes Example Using Prototype Design Pattern - Deep Copy Method
Lets define ShapeStyle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.LinePattern;
public class ShapeStyle {
protected Color lineColor;
protected LinePattern linePattern;
protected double lineThickness;
public ShapeStyle() {
super();
}
// prototype or deep copy constructor
public ShapeStyle(ShapeStyle shapeStyle) {
this();
System.out.println("Deep Copying ShapeStyle...");
this.lineColor = shapeStyle.lineColor;
this.linePattern = shapeStyle.linePattern;
this.lineThickness = shapeStyle.lineThickness;
}
public Color getLineColor() {
return lineColor;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
public LinePattern getLinePattern() {
return linePattern;
}
public void setLinePattern(LinePattern linePattern) {
this.linePattern = linePattern;
}
public double getLineThickness() {
return lineThickness;
}
public void setLineThickness(double lineThickness) {
this.lineThickness = lineThickness;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("lineColor=").append(lineColor).append(", linePattern=").append(linePattern)
.append(", lineThickness=").append(lineThickness);
return builder.toString();
}
}
Here's the code for FillStyle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.FillPattern;
public class FillStyle {
protected Color fillColor;
protected FillPattern fillPattern;
public FillStyle() {
super();
}
// prototype or deep copy constructor
public FillStyle(FillStyle fillStyle) {
super();
System.out.println("Deep Copying FillStyle...");
this.fillColor = fillStyle.fillColor;
this.fillPattern = fillStyle.fillPattern;
}
public Color getFillColor() {
return fillColor;
}
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
}
public FillPattern getFillPattern() {
return fillPattern;
}
public void setFillPattern(FillPattern fillPattern) {
this.fillPattern = fillPattern;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("fillColor=").append(fillColor).append(", fillPattern=").append(fillPattern);
return builder.toString();
}
}
Now, let's define the Shape abstract class.
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
public abstract class Shape {
protected int x;
protected int y;
protected ShapeStyle shapeStyle;
public Shape() {
super();
}
// prototype or deep copy constructor
public Shape(Shape shape) {
this();
System.out.println("Deep Copying Shape...");
this.x = shape.x;
this.y = shape.y;
this.shapeStyle = new ShapeStyle(shape.shapeStyle);
}
abstract void draw();
abstract String type();
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public ShapeStyle getStyle() {
return shapeStyle;
}
public void setStyle(ShapeStyle shapeStyle) {
this.shapeStyle = shapeStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("x=").append(x).append(", y=").append(y).append(", ").append(shapeStyle);
return builder.toString();
}
}
Here's the code for Circle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
public class Circle extends Shape {
protected int radius;
protected FillStyle fillStyle;
public Circle() {
super();
}
// prototype or deep copy constructor
public Circle(Circle circle) {
super(circle);
System.out.println("Deep Copying Circle...");
this.radius = circle.radius;
;
this.fillStyle = new FillStyle(circle.fillStyle);
}
public void draw() {
System.out.printf("Drawing Circle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Circle";
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("radius=").append(radius).append(", ").append(fillStyle);
return builder.toString();
}
}
Here's the code for Line class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
public class Line extends Shape {
protected int x1;
protected int y1;
public Line() {
super();
}
// prototype or deep copy constructor
public Line(Line line) {
super(line);
System.out.println("Deep Copying Line...");
this.x1 = line.x1;
this.y1 = line.y1;
}
public void draw() {
System.out.printf("Drawing Line (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Line";
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getY1() {
return y;
}
public void setY(int y1) {
this.y1 = y1;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("x1=").append(x1).append(", y1=").append(y1);
return builder.toString();
}
}
Here's the code for Rectangle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
public class Rectangle extends Shape {
protected int length;
protected int width;
protected FillStyle fillStyle;
public Rectangle() {
super();
}
// prototype or deep copy constructor
public Rectangle(Rectangle rectangle) {
super(rectangle);
System.out.println("Deep Copying Rectangle...");
this.length = rectangle.length;
this.width = rectangle.width;
this.fillStyle = new FillStyle(rectangle.fillStyle);
}
public void draw() {
System.out.printf("Drawing Rectangle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Rectangle";
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("length=").append(length).append(", width=").append(width).append(", ").append(fillStyle);
return builder.toString();
}
}
Here's the code for Triangle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
public class Triangle extends Shape {
protected int sideA;
protected int sideB;
protected int sideC;
protected FillStyle fillStyle;
public Triangle() {
super();
}
// prototype or deep copy constructor
public Triangle(Triangle triangle) {
super(triangle);
System.out.println("Deep Copying Triangle...");
this.sideA = triangle.sideA;
this.sideB = triangle.sideB;
this.sideC = triangle.sideC;
this.fillStyle = new FillStyle(triangle.fillStyle);
}
public void draw() {
System.out.printf("Drawing Triangle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Triangle";
}
public int getSideA() {
return sideA;
}
public void setSideA(int sideA) {
this.sideA = sideA;
}
public int getSideB() {
return sideB;
}
public void setSideB(int sideB) {
this.sideB = sideB;
}
public int getSideC() {
return sideC;
}
public void setSideC(int sideC) {
this.sideC = sideC;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("sideA=").append(sideA).append(", sideB=").append(sideB).append(", sideC=").append(sideC)
.append(", ").append(fillStyle);
return builder.toString();
}
}
Now its time to write Main class to execute and test the output:
xxxxxxxxxx
package org.trishinfotech.prototype.example1;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.FillPattern;
import org.trishinfotech.prototype.LinePattern;
public class Main {
public static void main(String[] args) {
Circle circle = new Circle();
circle.setX(10);
circle.setY(10);
ShapeStyle circleStyle = new ShapeStyle();
circleStyle.setLineColor(Color.BLUE);
circleStyle.setLinePattern(LinePattern.DOT);
circleStyle.setLineThickness(1.1d);
FillStyle circleFillStyle = new FillStyle();
circleFillStyle.setFillColor(Color.YELLOW);
circleFillStyle.setFillPattern(FillPattern.HEART);
circle.setStyle(circleStyle);
circle.setFillStyle(circleFillStyle);
System.out.println("Drawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Making Deep Copy of original object");
Circle deepCopyCircle = new Circle(circle);
System.out.println("Drawing deep copy object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
System.out.println("Modifying deep copy object");
deepCopyCircle.setX(20);
deepCopyCircle.getStyle().setLineColor(Color.RED);
deepCopyCircle.getFillStyle().setFillPattern(FillPattern.CHECKS);
System.out.println("\n\nDrawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Drawing deep copy object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
}
}
As you can see the creating original object requires so many statements to execute. But, we need just one statement to make a duplicate instance of the same. Later we can easily change the values we like to.
Below is the output:
xxxxxxxxxx
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Making Deep Copy of original object
Deep Copying Shape...
Deep Copying ShapeStyle...
Deep Copying Circle...
Deep Copying FillStyle...
Drawing deep copy object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Modifying deep copy object
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Drawing deep copy object
-------------------------------------------------------------------------
Drawing Circle (x=20, y=10, lineColor=RED, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=CHECKS).
Geometric Shapes Example Using Prototype Design Pattern - Clone Method
Now, lets do the same example using Cloneable interface. Here's the code for ShapeStyle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.LinePattern;
public class ShapeStyle implements Cloneable {
protected Color lineColor;
protected LinePattern linePattern;
protected double lineThickness;
public ShapeStyle() {
super();
}
// implemented clone method
protected ShapeStyle clone() throws CloneNotSupportedException {
return (ShapeStyle) super.clone();
}
public Color getLineColor() {
return lineColor;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
public LinePattern getLinePattern() {
return linePattern;
}
public void setLinePattern(LinePattern linePattern) {
this.linePattern = linePattern;
}
public double getLineThickness() {
return lineThickness;
}
public void setLineThickness(double lineThickness) {
this.lineThickness = lineThickness;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("lineColor=").append(lineColor).append(", linePattern=").append(linePattern)
.append(", lineThickness=").append(lineThickness);
return builder.toString();
}
}
Here's the code for FillStyle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.FillPattern;
public class FillStyle implements Cloneable {
protected Color fillColor;
protected FillPattern fillPattern;
public FillStyle() {
super();
}
// implemented clone method
public FillStyle clone() throws CloneNotSupportedException {
return (FillStyle) super.clone();
}
public Color getFillColor() {
return fillColor;
}
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
}
public FillPattern getFillPattern() {
return fillPattern;
}
public void setFillPattern(FillPattern fillPattern) {
this.fillPattern = fillPattern;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("fillColor=").append(fillColor).append(", fillPattern=").append(fillPattern);
return builder.toString();
}
}
Here's the code Shape abstract class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
public abstract class Shape implements Cloneable {
protected int x;
protected int y;
protected ShapeStyle shapeStyle;
public Shape() {
super();
}
// implemented clone method
public Shape clone() throws CloneNotSupportedException {
Shape shape = (Shape) super.clone();
// call explicit clone for handling cloning of nested objects
shape.shapeStyle = shapeStyle.clone();
return shape;
}
abstract void draw();
abstract String type();
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public ShapeStyle getStyle() {
return shapeStyle;
}
public void setStyle(ShapeStyle shapeStyle) {
this.shapeStyle = shapeStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("x=").append(x).append(", y=").append(y).append(", ").append(shapeStyle);
return builder.toString();
}
}
Here's the code for Circle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
public class Circle extends Shape {
protected int radius;
protected FillStyle fillStyle;
public Circle() {
super();
}
// implemented clone method
public Circle clone() throws CloneNotSupportedException {
System.out.println("Cloning Circle...");
Circle circle = (Circle) super.clone();
// call explicit clone for handling cloning of nested objects
circle.fillStyle = fillStyle.clone();
return circle;
}
public void draw() {
System.out.printf("Drawing Circle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Circle";
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("radius=").append(radius).append(", ").append(fillStyle);
return builder.toString();
}
}
Here's the code for Line class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
public class Line extends Shape {
protected int x1;
protected int y1;
public Line() {
super();
}
// implemented clone method
public Line clone() throws CloneNotSupportedException {
System.out.println("Cloning Rectangle...");
return (Line) super.clone();
}
public void draw() {
System.out.printf("Drawing Line (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Line";
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getY1() {
return y;
}
public void setY(int y1) {
this.y1 = y1;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("x1=").append(x1).append(", y1=").append(y1);
return builder.toString();
}
}
Here's the code for Rectangle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
public class Rectangle extends Shape {
protected int length;
protected int width;
protected FillStyle fillStyle;
public Rectangle() {
super();
}
// implemented clone method
public Rectangle clone() throws CloneNotSupportedException {
System.out.println("Cloning Rectangle...");
Rectangle rectangle = (Rectangle) super.clone();
// call explicit clone for handling cloning of nested objects
rectangle.fillStyle = fillStyle.clone();
return rectangle;
}
public void draw() {
System.out.printf("Drawing Rectangle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Rectangle";
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("length=").append(length).append(", width=").append(width).append(", ").append(fillStyle);
return builder.toString();
}
}
Here's the code for Triangle class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
public class Triangle extends Shape {
protected int sideA;
protected int sideB;
protected int sideC;
protected FillStyle fillStyle;
public Triangle() {
super();
}
// implemented clone method
public Triangle clone() throws CloneNotSupportedException {
System.out.println("Cloning Triangle...");
Triangle triangle = (Triangle) super.clone();
// call explicit clone for handling cloning of nested objects
triangle.fillStyle = fillStyle.clone();
return triangle;
}
public void draw() {
System.out.printf("Drawing Triangle (%s, %s).\n", super.toString(), this.toString());
}
String type() {
return "Triangle";
}
public int getSideA() {
return sideA;
}
public void setSideA(int sideA) {
this.sideA = sideA;
}
public int getSideB() {
return sideB;
}
public void setSideB(int sideB) {
this.sideB = sideB;
}
public int getSideC() {
return sideC;
}
public void setSideC(int sideC) {
this.sideC = sideC;
}
public FillStyle getFillStyle() {
return fillStyle;
}
public void setFillStyle(FillStyle fillStyle) {
this.fillStyle = fillStyle;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("sideA=").append(sideA).append(", sideB=").append(sideB).append(", sideC=").append(sideC)
.append(", ").append(fillStyle);
return builder.toString();
}
}
Now let's write Main class to execute and test the output:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.FillPattern;
import org.trishinfotech.prototype.LinePattern;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Circle circle = new Circle();
circle.setX(10);
circle.setY(10);
ShapeStyle circleStyle = new ShapeStyle();
circleStyle.setLineColor(Color.BLUE);
circleStyle.setLinePattern(LinePattern.DOT);
circleStyle.setLineThickness(1.1d);
FillStyle circleFillStyle = new FillStyle();
circleFillStyle.setFillColor(Color.YELLOW);
circleFillStyle.setFillPattern(FillPattern.HEART);
circle.setStyle(circleStyle);
circle.setFillStyle(circleFillStyle);
System.out.println("Drawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Making clone of original object");
Circle deepCopyCircle = circle.clone();
System.out.println("Drawing clone object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
System.out.println("Modifying clone object");
deepCopyCircle.setX(20);
deepCopyCircle.getStyle().setLineColor(Color.RED);
deepCopyCircle.getFillStyle().setFillPattern(FillPattern.CHECKS);
System.out.println("\n\nDrawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Drawing clone object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
}
}
Almost same code with the help of clone() method. Below is the output:
xxxxxxxxxx
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Making clone of original object
Cloning Circle...
Drawing clone object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Modifying clone object
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Drawing clone object
-------------------------------------------------------------------------
Drawing Circle (x=20, y=10, lineColor=RED, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=CHECKS).
Geometric Shapes Example Using Prototype Design Pattern - Clone + Prototype Registry Method
Lets write a registry class to hold all of the shape objects we have. We will use a map to cache the shape object prototypes. And hence we will use shape-type as the key for caching. We can have different ways of implementation of this cache-registry. So, feel free to write your own as per your use case.
Here's code for ShapeRegistry class:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
import java.util.HashMap;
import java.util.Map;
public class ShapeRagistry {
protected static Map<String, Shape> CACHE = new HashMap<String, Shape>();
public static Shape getByType(String type) {
return CACHE.get(type);
}
public static void addShape(Shape shape) throws CloneNotSupportedException {
CACHE.put(shape.type(), shape.clone());
}
}
Here we can see that I have added methods for getting and adding the prototype. We can also have a predefined pool of prototype objects using static block or constructor.
And now we will write our Main class to execute and test the output:
xxxxxxxxxx
package org.trishinfotech.prototype.example2;
import org.trishinfotech.prototype.Color;
import org.trishinfotech.prototype.FillPattern;
import org.trishinfotech.prototype.LinePattern;
public class ShapeRegistryMain {
public static void main(String[] args) throws CloneNotSupportedException {
Circle circle = new Circle();
circle.setX(10);
circle.setY(10);
ShapeStyle circleStyle = new ShapeStyle();
circleStyle.setLineColor(Color.BLUE);
circleStyle.setLinePattern(LinePattern.DOT);
circleStyle.setLineThickness(1.1d);
FillStyle circleFillStyle = new FillStyle();
circleFillStyle.setFillColor(Color.YELLOW);
circleFillStyle.setFillPattern(FillPattern.HEART);
circle.setStyle(circleStyle);
circle.setFillStyle(circleFillStyle);
System.out.println("Drawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Making clone of original object");
// check the registry if its already available at there.
Circle deepCopyCircle = (Circle) ShapeRagistry.getByType(circle.type());
if (deepCopyCircle == null) {
// add it in the registry if its not available
ShapeRagistry.addShape(circle);
}
// get the clone always from the regeistry and use.
deepCopyCircle = (Circle) ShapeRagistry.getByType(circle.type());
System.out.println("Drawing clone object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
System.out.println("Modifying clone object");
deepCopyCircle.setX(20);
deepCopyCircle.getStyle().setLineColor(Color.RED);
deepCopyCircle.getFillStyle().setFillPattern(FillPattern.CHECKS);
System.out.println("\n\nDrawing original object");
System.out.println("-------------------------------------------------------------------------");
circle.draw();
System.out.println("Drawing clone object");
System.out.println("-------------------------------------------------------------------------");
deepCopyCircle.draw();
}
}
Below is the output of the program:
xxxxxxxxxx
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Making clone of original object
Cloning Circle...
Drawing clone object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Modifying clone object
Drawing original object
-------------------------------------------------------------------------
Drawing Circle (x=10, y=10, lineColor=BLUE, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=HEART).
Drawing clone object
-------------------------------------------------------------------------
Drawing Circle (x=20, y=10, lineColor=RED, linePattern=DOT, lineThickness=1.1, radius=0, fillColor=YELLOW, fillPattern=CHECKS).
The Source Code can be found here: Prototype-Design-Pattern-Sample-Code
Liked the article? Please don't forget to press that like button. Happy coding!
Need more articles, please visit my profile: Brijesh Saxena
Opinions expressed by DZone contributors are their own.
Comments