什么是原型模式?
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
当我们程序中有几个相似但又不太一样的对象时,就可以使用原型模式。简单一些说的话,就是通过深拷贝的方法用原型实例指定创建对象的种类。
Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
图示
我们可以举个例子,比如现在有三个形状对象,圆形(Circle),正方形(Square),长方形(Rectangle)。现在我们想要通过原型模式创建这三个对象,那就需要有一个原型实例 :形状(Shape),让它实现java的接口类Cloneable,并且重写克隆方法clone()。
然后我们定义一个类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。最后通过PrototypePatternDemo 类使用 ShapeCache 类来获取 Shape 对象。
实现
步骤1
//定义原型类,实现java接口
public abstract class Shape implements Cloneable{
private String id;
protected String type;
//需要子类实现的方法
abstract void draw();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
//重写克隆类
public Object clone(){
Object clone = null;
try{
clone = super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return clone;
}
}
步骤2
实现具体对象 圆形(Circle),正方形(Square),长方形(Rectangle)
public class Circle extends Shape{
public Circle(){
type = "Circle";
}
@Override
void draw() {
System.out.println("Inside Circle::draw() method");
}
}
public class Square extends Shape{
public Square(){
type = "Square";
}
@Override
void draw() {
System.out.println("Inside Square::draw() method");
}
}
public class Rectangle extends Shape{
public Rectangle(){
type = "Rectangle";
}
@Override
void draw() {
System.out.println("Inside Rectangle::draw() method");
}
}
步骤3
通过调用原型对象克隆方法,创建指定对象
import java.util.Hashtable;
public class ShapeCache {
private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>();
public static Shape getShape(String shapeId){
Shape shapeCache = shapeMap.get(shapeId);
return (Shape)shapeCache.clone();
}
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);
}
}
步骤4
main()方法检查结果
public class PrototypePattenDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape cloneShape1 = (Shape)ShapeCache.getShape("1");
System.out.println("Shape: "+ cloneShape1.getType());
System.out.println("Shape: "+ cloneShape1.getId());
cloneShape1.draw();
System.out.println("------------------------------");
Shape cloneShape2 = (Shape)ShapeCache.getShape("2");
System.out.println("Shape: "+ cloneShape2.getType());
System.out.println("Shape: "+ cloneShape2.getId());
cloneShape2.draw();
System.out.println("------------------------------");
Shape cloneShape3 = (Shape)ShapeCache.getShape("3");
System.out.println("Shape: "+ cloneShape3.getType());
System.out.println("Shape: "+ cloneShape3.getId());
cloneShape3.draw();
System.out.println("------------------------------");
}
}