今天让我们讨论另一个创新的设计模式-原型设计模式。
原型设计模式
基本实施基本实施
原型注册表实施
在该模式的原型注册表实现中,我们创建一个注册表类来缓存对象以进行原型制作。在其他世界中,我们使用原型收集和管理服务或类,使所有原型都可访问并可用于原型制作。 缓存注册表的目的是在内存中维护原型就绪对象池。 为了更好地理解这一点,让我们看一个几何形状的例子。我将示例保持相对简单,以将重点放在模式上。
首先让我们定义几个常见的枚举,在实现原型模式时,将在每种不同的方法中使用这些枚举。
在这里,颜色枚举的代码:
package org.trishinfotech.prototype; public enum Color { RED, GREEN, BLUE, YELLOW, WHITE, BLACK, ORANGE, MAROON }
在这里,是LinePattern枚举的代码。我们将使用这些线型绘制不同的几何形状。
package org.trishinfotech.prototype; public enum LinePattern { SOLID, DASH, DOT, DOUBLE_DASH, DASH_SPACE }
在这里,是FillPattern枚举的代码。我们将使用这些填充图案来绘制不同的几何形状。
package org.trishinfotech.prototype; public enum FillPattern { SOLID, DASH, DOT, CHECKS, HEART; }
使用原型设计模式的几何形状示例-深度复制方法 让我们定义ShapeStyle 类:
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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("lineColor=").append(lineColor).append(", linePattern=").append(linePattern) .append(", lineThickness=").append(lineThickness); return builder.toString(); } }
这是FillStyle 类的代码:
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; } @Override 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.
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; } @Override 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:
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); } @Override public void draw() { System.out.printf("Drawing Circle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override 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:
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; } @Override public void draw() { System.out.printf("Drawing Line (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override 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:
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); } @Override public void draw() { System.out.printf("Drawing Rectangle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override 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:
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); } @Override public void draw() { System.out.printf("Drawing Triangle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override 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(); } }
现在是时候编写Main 类来执行和测试输出了:
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(); } }
如您所见,创建原始对象需要执行许多语句。但是,我们只需要一个语句即可复制相同的实例。稍后,我们可以轻松更改所需的值。
以下是输出:
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).
使用原型设计模式的几何形状示例-克隆方法 现在,让我们使用Cloneable 接口做同样的例子。这是ShapeStyle 类的代码:
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 @Override protected ShapeStyle clone return (ShapeStyle) } 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("lineColor=").append(lineColor).append(", linePattern=").append(linePattern) .append(", lineThickness=").append(lineThickness); return builder.toString(); } }
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 @Override 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("fillColor=").append(fillColor).append(", fillPattern=").append(fillPattern); return builder.toString(); } }
这是Shape 抽象类的代码:
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 @Override 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("x=").append(x).append(", y=").append(y).append(", ").append(shapeStyle); return builder.toString(); } }
这是Circle 类的代码:
package org.trishinfotech.prototype.example2; public class Circle extends Shape { protected int radius; protected FillStyle fillStyle; public Circle() { super(); } // implemented clone method @Override 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; } @Override public void draw() { System.out.printf("Drawing Circle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("radius=").append(radius).append(", ").append(fillStyle); return builder.toString(); } }
这是Line 类的代码:
package org.trishinfotech.prototype.example2; public class Line extends Shape { protected int x1; protected int y1; public Line() { super(); } // implemented clone method @Override public Line clone() throws CloneNotSupportedException { System.out.println("Cloning Rectangle..."); return (Line) super.clone(); } @Override public void draw() { System.out.printf("Drawing Line (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("x1=").append(x1).append(", y1=").append(y1); return builder.toString(); } }
这是Rectangle 类的代码:
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 @Override 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; } @Override public void draw() { System.out.printf("Drawing Rectangle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("length=").append(length).append(", width=").append(width).append(", ").append(fillStyle); return builder.toString(); } }
这是Triangle 类的代码:
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 @Override 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; } @Override public void draw() { System.out.printf("Drawing Triangle (%s, %s).\n", super.toString(), this.toString()); } @Override 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; } @Override 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(); } }
现在让我们编写Main 类来执行和测试输出:
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(); } }
借助clone()方法几乎相同的代码。以下是输出:
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).
使用原型设计模式的几何形状示例-克隆+原型注册表方法 让我们编写一个注册表类来保存我们拥有的所有形状对象。我们将使用地图来缓存形状对象原型。因此,我们将使用shape-type作为缓存的关键。我们可以采用不同的方式来实现此缓存注册表。因此,可以根据您的用例随意编写自己的代码。
以下是ShapeRegistry类的代码:
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()); } }
在这里我们可以看到我已经添加了获取和添加原型的方法。我们还可以使用静态块或构造函数来预定义原型对象池。
现在,我们将编写 Main 类来执行和测试输出:
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(); } }
下面是程序的输出:
源代码可以在这里找到: 原型设计模式样本代码
原文链接:http://codingdict.com