定义
使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
注意点
通过该模式创建的对象是全新的对象,在内部中拥有新的地址。
角色
Prototype(抽象原型类)
声明克隆方法的接口,是所有具体原型类的公共父类。
ConcretePrototype(具体原型类)
抽象原型类中方法的具体实现。
Client(客户类)
让一个原型对象克隆自身从而创建一个新的对象。
实现方法(Java)
浅拷贝
通过实现Cloneable接口快速实现。
public class Student implements Cloneable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public Student clone() {
Object object = null;
try {
object = super.clone();
return (Student) object;
} catch (CloneNotSupportedException e) {
System.out.println("不支持复制");
return null;
}
}
public static void main(String[] args) {
Student xiaohong = new Student("小红", 12);
Student copy = xiaohong.clone();
copy.setName("copy");
copy.setAge(18);
System.out.println(xiaohong.toString());
System.out.println(copy.toString());
}
}
测试结果:
Student{name='小红', age=12}
Student{name='copy', age=18}
深拷贝
要点:均实现Serializable接口。 父亲类:
public class Father implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Father(String name, int age) {
this.name = name;
this.age = age;
}
}
家庭类:
public class Family implements Serializable {
private Father father;
public Father getFather() {
return father;
}
public void setFather(Father father) {
this.father = father;
}
public Family deepClone() throws IOException, ClassNotFoundException {
// 将对象写入流中
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(bao);
oss.writeObject(this);
// 将对象从流中取出
ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Family) ois.readObject();
}
public static void main(String[] args) {
Father father =new Father("小头爸爸",20);
Family family1 =new Family();
family1.setFather(father);
Family family2 = null;
try {
family2 = family1.deepClone();
}catch (Exception e){
System.out.println("深拷贝失败");
}
System.out.println(family1 == family2);
System.out.println(family1.getFather() == family2.getFather());
}
}
测试结果:
false
false
适用场景
(1)批量创建相似的复杂对象。
(2)系统需要保存对象的状态,且对象的状态变化很小,亦或是对象本身占用的内存很小。
(3)需要避免分层次的工厂类来创建分层次的对象,且类的实例对象只有一个或很少的几个组合状态。