原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
概述
原型模式是从一个对象出发得到一个和自己有相同状态的新对象的成熟模式,该模式的关键是将一个对象定义为原型,并为其提供复制自己的方法。
java.lang.Object类的clone方法
参见《java中的深浅克隆》
适用性
1.当一个系统应该独立于它的产品创建、构成和表示时。
2.当要实例化的类是在运行时刻指定时,例如,通过动态装载。
3.为了避免创建一个与产品类层次平行的工厂类层次时。
4.当一个类的实例只能有几个不同状态组合中的一种时。 建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
参与者
1. Prototype 声明一个克隆自身的接口。
2. ConcretePrototype 实现一个克隆自身的操作。
3. Client 让一个原型克隆自身从而创建一个新的对象。
原型模式的结构与使用
模式的结构中包括两种角色:
•抽象原型(Prototype)
•具体原型(Concrete Prototype)
模式的UML类图:
实战部分
【例1】:实现一个克隆接口,然后实现一个克隆自身的操作并加以应用
1.抽象原型(Prototype): Prototype.java
public interface Prototype { public Object cloneMe() throws CloneNotSupportedException; }
2.具体原型(Concrete Prototype)_1: Cubic.java
public class Cubic implements Prototype, Cloneable{ double length, width, height; Cubic(double a, double b, double c){ length = a; width = b; height = c; } public Object cloneMe() throws CloneNotSupportedException{ Cubic object = (Cubic)clone(); return object; } }
2.具体原型(Concrete Prototype)_2 : Goat.java
import java.io.*; public class Goat implements Prototype,Serializable{ StringBuffer color; public void setColor(StringBuffer c){ color = c; } public StringBuffer getColor(){ return color; } public Object cloneMe() throws CloneNotSupportedException{ Object object = null; try{ ByteArrayOutputStream outOne = new ByteArrayOutputStream(); ObjectOutputStream outTwo = new ObjectOutputStream(outOne); outTwo.writeObject(this); ByteArrayInputStream inOne= new ByteArrayInputStream(outOne.toByteArray()); ObjectInputStream inTwo = new ObjectInputStream(inOne); object=inTwo.readObject(); } catch(Exception event){ System.out.println(event); } return object; } }
3.应用 Application.java
public class Application { 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 ex){} 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 ex){} } }
原型模式的优点
•当创建类的新实例的代价更大时,使用原型模式复制一个已有的实例可以提高创建新实例的效率。
•可以动态地保存当前对象的状态。在运行时刻,可以随时使用对象流保存当前对象的一个复制品。