定义:用原型实例指定创建对象,并通过拷贝这些原型创建新的对象
![](https://i-blog.csdnimg.cn/blog_migrate/2b2a46110dcd763a189cb3d63199d587.png)
Prototype: 声明一个克隆自身的接口,用来约束想要克隆自己的类,要求它们都要实现这里定义的克隆方法。
ConcretePrototye: 实现Prototype接口的类,这些类真正实现了克隆自身的功能
Client: 使用原型的客户端,首先要获取到原型实例对象,然后通过原型实例克隆自身来创建新的对象实例。
public interface Prototype {
/**
* 克隆自身的一个方法
* @return 一个从自身克隆出来的对象
*/
public Prototype clone();
}
/**
* 克隆的具体对象
*/
public class ConcretePrototype1 implements Prototype {
@Override
public Prototype clone() {
//最简单的克隆,新建一个自身对象,由于没有属性,就不再复制值了
Prototype prototype = new ConcretePrototype1();
return prototype;
}
}
/**
* 克隆的具体对象
*/
public class ConcretePrototype2 implements Prototype {
@Override
public Prototype clone() {
//最简单的克隆,新建一个自身对象,由于没有属性,就不再复制值了
Prototype prototype = new ConcretePrototype2();
return prototype;
}
}
/**
* 使用原型的客户端
*/
public class Client {
/**
* 持有需要使用的原型接口对象
*/
private Prototype prototype;
/**
* 构造方法,传入需要使用的原型接口对象
* @param prototype 需要使用的原型接口对象
*/
public Client(Prototype prototype) {
this.prototype = prototype;
}
/**
* 示意方法,执行某个功能操作
*/
public void operation() {
Prototype newPrototype = prototype.clone();
}
}
原型模式的功能
1. 通过克隆来创建新的对象实例
2. 克隆出来的新的对象实例复制原型实例属性的值
原型模式与new的区别
new一个实例对象,一般属性是没有值的,或者只有默认值;如果是克隆得到一个实例,通常属性是有值的,属性的值就是原型对象实例在克隆的时候,原型对象实例的属性的值
原型模式主要就是为了通过克隆来创建新的对象实例,在Java中Object类提供了clone方法,需要克隆功能的类,只需实现java.lang.Cloneable接口。
从Cloneable文档中,可以知道实现Cloneable接口时clone方法由protected转为public,接口中并未有任何实现,只是作为一个标记的作用,明细需要查看Object类中的描述。
再查看Object文档中(如下),可以得知数组类默认实现Cloneable接口,关于克隆会有shallow copy和deep copy两种情况
The method {@code clone} for class {@code Object} performs a specific cloning operation. First, if the class of this object does not implement the interface {@code Cloneable}, then a {@code CloneNotSupportedException} is thrown. Note that all arrays are considered to implement the interface {@code Cloneable} and that the return type of the {@code clone} method of an array type {@code T[]} is {@code T[]} where T is any reference or primitive type. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.
关于shallow copy和deep copy的内容较多,此处略谈,详细可以参考另一篇文章浅拷贝(shallow copy)和深拷贝(deep copy),此篇文章主要是介绍设计模式。
shallow copy:只负责克隆按值传递的数据(比如基本数据类型、String类型)
deep copy:除了shallow copy的值外,还负责克隆引用类型的数据,基本是就是被克隆实例所有的属性数据都会被克隆出来。(注意:如果被克隆的对象里面的属性数据是引用类型,也就是属性的类型也是对象,则需要一直递归克隆下去。这也意味着要深度克隆成功,必须要整个克隆所涉及的对象都要正确实现克隆方法,如果其中一个没有正确,则会导致克隆失败)
原型模式的优点:
对客户端隐藏具体的实现类型
在运行时动态改变具体的实现类型
原型模式的缺点
每个原型的子类都必须实现clone 的操作,尤其在包含引用类型的对象时,clone方法会比较麻烦,必须要能够递归地让所有的相关对象都要正确的实现克隆