Design Pattern 简明教程

Design Patterns - Prototype Pattern

原型模式指的是在考虑性能的情况下创建副本对象。这种设计模式属于创建模式,因为这种模式提供了创建对象的一种最好的方法。

Prototype pattern refers to creating duplicate object while keeping performance in mind. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

此模式涉及实现一个原型接口,表示要创建当前对象的克隆。当直接创建对象代价较高时,将使用此模式。例如,要在代价高昂的数据库操作后创建一个对象。我们可以缓存对象,在下一个请求上返回其克隆,并按需更新数据库,从而减少数据库调用。

This pattern involves implementing a prototype interface which tells to create a clone of the current object. This pattern is used when creation of object directly is costly. For example, an object is to be created after a costly database operation. We can cache the object, returns its clone on next request and update the database as and when needed thus reducing database calls.

Implementation

我们将创建一个抽象类 Shape 和扩展 Shape 类的具体类。接下来定义一个 ShapeCache 类,它将 shape 对象存储在哈希表中,并在请求时返回它们的克隆。

We’re going to create an abstract class Shape and concrete classes extending the Shape class. A class ShapeCache is defined as a next step which stores shape objects in a Hashtable and returns their clone when requested.

我们的演示类 PrototypPatternDemo 将使用 ShapeCache 类获取 Shape 对象。

PrototypPatternDemo, our demo class will use ShapeCache class to get a Shape object.

prototype pattern uml diagram

Step 1

创建一个实现 Clonable 接口的抽象类。

Create an abstract class implementing Clonable interface.

Shape.java

public abstract class Shape implements Cloneable {

   private String id;
   protected String type;

   abstract void draw();

   public String getType(){
      return type;
   }

   public String getId() {
      return id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public Object clone() {
      Object clone = null;

      try {
         clone = super.clone();

      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }

      return clone;
   }
}

Step 2

创建一个扩展上述类的具体类。

Create concrete classes extending the above class.

Rectangle.java

public class Rectangle extends Shape {

   public Rectangle(){
     type = "Rectangle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Square.java

public class Square extends Shape {

   public Square(){
     type = "Square";
   }

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle.java

public class Circle extends Shape {

   public Circle(){
     type = "Circle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Step 3

创建一个类从数据库中获取具体类并将它们存储​​在哈希表中。

Create a class to get concrete classes from database and store them in a Hashtable.

ShapeCache.java

import java.util.Hashtable;

public class ShapeCache {

   private static Hashtable<String, Shape> shapeMap  = new Hashtable<String, Shape>();

   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }

   // for each shape run database query and create shape
   // shapeMap.put(shapeKey, shape);
   // for example, we are adding three shapes

   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);

      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);

      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(), rectangle);
   }
}

Step 4

PrototypePatternDemo 使用 ShapeCache 类从存储在哈希表中的形状中获取克隆。

PrototypePatternDemo uses ShapeCache class to get clones of shapes stored in a Hashtable.

PrototypePatternDemo.java

public class PrototypePatternDemo {
   public static void main(String[] args) {
      ShapeCache.loadCache();

      Shape clonedShape = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());

      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());

      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());
   }
}

Step 5

验证输出。

Verify the output.

Shape : Circle
Shape : Square
Shape : Rectangle