介绍
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
应用场景
(1)程序需要从一个对象出发,得到若干个和其状态相同,并可独立变化其状态的对象时。
(2)当对象的创建需要独立于它的构造过程和表示时。
(3)一个类创建实例后是新对象,那么就可以将这个类的一个实例定义为原型,通过复制该原型得到新的实例比使用类的构造方法创建实例更方便。
模式结构
(1)抽象原型(Prototype):一个接口或抽象类,负责定义对象复制自身的方法。
(2)具体原型(ConcretePrototype):实现Prototype接口的类,具体原型实现抽象原型中的方法,以便所创建的对象调用该方法复制自己。
代码案例
首先,创建抽象原型:
public interface Prototype {
Object cloneMe() throws CloneNotSupportedException;
}
创建立方体类:
public class Cubic implements Prototype , Cloneable{
double length , width , height;
Cubic(double a,double b,double c){
length = a;
width = b;
height = c;
}
@Override
public Object cloneMe() throws CloneNotSupportedException{
return clone();
}
}
山羊类:
public class Goat implements Prototype, Cloneable {
private StringBuffer color;
public void setColor(StringBuffer c){
color = c;
}
public StringBuffer getColor(){
return color;
}
@Override
public Object cloneMe() throws CloneNotSupportedException {
return clone();
}
}
测试类:
public static void main(String[] args){
Cubic cubic = new Cubic(12,20,66);
System.out.println("cubic的长、宽和高:");
System.out.println(cubic.length+","+cubic.width+","+cubic.height);
try{
Cubic cubicCopy = (Cubic) cubic.cloneMe();
System.out.println("cubicCopy的长、宽和高:");
System.out.println(cubicCopy.length+","+cubicCopy.width+","+cubicCopy.height);
} catch(CloneNotSupportedException e){
e.printStackTrace();
}
System.out.println("--------------------------");
Goat goat = new Goat();
goat.setColor(new StringBuffer("白颜色的山羊"));
System.out.println("goat是"+goat.getColor());
Goat goatCopy = null;
try {
goatCopy = (Goat)goat.cloneMe();
System.out.println("goatCopy是"+goatCopy.getColor());
System.out.println("goatCopy将自己的颜色变成黑色");
goatCopy.setColor(new StringBuffer("黑颜色的山羊"));
System.out.println("goat仍然是"+goat.getColor());
System.out.println("goatCopy是"+goatCopy.getColor());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
优点
(1)性能提高。
(2)逃避构造函数的约束。
缺点
(1)必须实现 Cloneable 接口。