定义:
使用原型实例指定创建对象的种类,并通过拷贝这个原型的属性创建新的对象。
结构图:
- Prototype:抽象原型类,声明克隆方法的接口,并是所有原型类的公共父类。在Java中,Object类为该角色。
- ConcretePrototype:具体原型类,实现克隆方法,返回自己的一个克隆对象。
- Client:从一个已有的原型对象,调用其克隆方法,获得该对象的克隆对象,针对抽象原型类编程,方便进行扩展和修改。
浅克隆(Shallow Clone)
- 浅克隆中,如果原型对象的成员变量是值类型,则进行复制,不会相互影响,如果是引用类型,则将其地址复制,实质上指向的是同一个对象。
- 在Java语言中可以覆盖Object中的clone()方法来实现浅克隆,其中具体原型类必需要实现Cloneable接口。如果没有实现这个接口,则会抛出CloneNotSupportedException。
class ConcretePrototype implements Cloneable
{
……
public Prototype clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("Not support cloneable");
}
return (Prototype )object;
}
……
}
深克隆(Deep Clone)
- 无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。
- 在Java中可以通过序列化(Serialization)来进行深克隆,即原型对象实现Serializable接口,然后写入到ObjectOutputStream,则从该Stream读出对象即可。
//使用序列化技术实现深克隆
public object deepClone() throws IOException, ClassNotFoundException, OptionalDataException{
//将对象写入流中
ByteArrayOutputStream bao=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bao);
oos.writeObject(this);
//将对象从流中取出
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return (WeeklyLog)ois.readObject();
}
原型管理器
原型管理器是将多个原型对象存储在一个集合中供客户端使用,专门负责克隆对象的工厂,类似于简单工厂方法,通过key来获取一个新的对象。
- 原型管理器中往往使用一个HashTable来管理所有原型对象。
- 可以提供一个默认的原型对象,如果有新的写入,可以将原有的对象进行覆盖。
- 读取时,从HashTable中获得原型对象,然后调用原型对象的clone方法获得一个新的对象。
优点:
- 当创建一个对象比较复杂时,原型模式可以简化其创建过程,通过复制获得和已有实例相同的对象。
- 简化创建结构,不需要专门的工厂存在,仅需要实现克隆方法即可。
缺点:
- 克隆方法位于类的内部,家中了类的职责,对已有类进行改造时,需要修改源码。
- 在实现深克隆时需要较为复杂的代码,存在多重嵌套的问题。
适用场景:
- 创建新对象的成本比较大,新的对象可以通过原型模式对已有对象进行复制来获得。
- 如果系统要保存对象状态,并且对象本身占用内存很少,可以使用原型模式配合备忘录模式来实现。
实例: