定义:
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
在 Java 中 Prototype 模式变成 clone()方法的使用,由于 Java 的纯洁的面向对象特性,使得在 Java 中使用设计模式变
得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如 Interator 遍历模式。
·模式的UML类图:
/** * describe 抽象模型 */ public interface Prototype { public Object cloneMe() throws CloneNotSupportedException; }
/** * describe 具体模型 */ public class Cubic implements Prototype , Cloneable { private double length , width , height; public Cubic (double length , double width , double height ){ this.length = length; this.width = width; this.height = height; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } @Override public Object cloneMe() throws CloneNotSupportedException { Cubic object = (Cubic)this.clone(); // 调用从Object类继承的clone()方法 return object; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
/** * describe 具体模型 */ public class Goat implements Prototype , Cloneable { StringBuffer color; public void setColor(StringBuffer c) { color = c; } public StringBuffer getColor() { return color; } @Override public Object cloneMe() throws CloneNotSupportedException { Object object = null; try { object = this.clone(); } catch (Exception event) { System.out.println(event); } return object; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public class Tests { @Test public void test() { Cubic cubic = new Cubic(12 , 20 , 66); System.out.print("cubic的长、宽和高:"); System.out.println(cubic.getLength() + "," + cubic.getWidth() + "," + cubic.getHeight()); try { Cubic cubicCopy = (Cubic)cubic.cloneMe(); System.out.print("cubicCopy的长、宽和高:"); System.out.println(cubicCopy.getLength() + "," + cubicCopy.getWidth() + "," + cubicCopy.getHeight()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } Goat goat = new Goat(); goat.setColor(new StringBuffer("白颜色的山羊")); System.out.println("goat是" + goat.getColor()); try { Goat 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(); } } }
模式的优点
·当创建类的新实例的代价更大时,使用原型模式复制一个已有的实例可以提高创建新实例的效率。
·可以动态地保存当前对象的引用。在运行时,可以随时使用对象流保存当前对象的一个复制品。
·可以在运行时创建新的对象,而无须创建一系列类和继承结构。
·可以动态地添加、删除原型的复制品。
适用的情景
·程序需要从一个对象出发,得到若干个和其状态相同,并可独立变化其状态的对象时。
·当程序的创建需要独立于它的过程和表示时。
·一个类创建状态不是很多,那么就可以将这个类的一个实例定义为原型,那么通过复制该原型得到新的实例可能比重新使用类的构造方法创建新实例更方便。
具体的实例
·java.lang.Object类的clone()方法,及Cloneable接口。
·Serializable接口。
·克隆容器。