三、原型模式
1. 概述
- 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象
2. 结构
- 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
- 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
- 访问类:使用具体原型类中的 clone() 方法来复制新的对象。
3. 实现
(浅克隆和深克隆)
3.1 浅克隆
定义
:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原 有属性所指向的对象的内存地址。使用场景
:①对象的创建非常复杂,可以使用原型模式快捷的创建对象; ②性能和安全要求比较高。
Java中的Object类中提供了 clone() 方法来实现浅克隆。 Cloneable 接口是上面的类图中的抽 象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。
3.1.1 案例1
- UML

- graduates类
public class graduates implements Cloneable{
private String name;
public void setName(String name) {
this.name = name;
}
public graduates() {
System.out.println("创建了一个毕业生");
}
public void show(String name){
System.out.println(name+"恭喜你毕业了");
}
@Override
protected graduates clone() throws CloneNotSupportedException {
System.out.println("我是克隆的");
return (graduates) super.clone();
}
}
- 测试类
public class testGraduates {
public static void main(String[] args) throws CloneNotSupportedException {
graduates graduates = new graduates();
graduates.show("张三");
System.out.println("=============");
//克隆的不走原型类的构造方法
graduates graduates1 = graduates.clone();
graduates1.show("李四");
}
}
- 测试结果
创建了一个毕业生
张三恭喜你毕业了
=============
我是克隆的
李四恭喜你毕业了
3.1.2 案例2
- UML

- graduates类
public class graduates implements Cloneable {
private Student stu;
public void setStu(Student stu) {
this.stu = stu;
}
public Student getStu() {
return stu;
}
public void show() {
System.out.println(stu.getName() + "恭喜你,毕业了");
}
@Override
protected graduates clone() throws CloneNotSupportedException {
System.out.println("我是克隆的");
return (graduates) super.clone();
}
}
- 学生类
public class Student {
private String name;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 测试类
public class testGraduates {
public static void main(String[] args) throws CloneNotSupportedException {
graduates graduates = new graduates();
Student stu = new Student();
stu.setName("张三");
graduates.setStu(stu);
graduates.show();
System.out.println("=============");
graduates graduates1 = graduates.clone();
Student stu1 = graduates1.getStu();
stu1.setName("李四");
graduates1.setStu(stu1);
graduates1.show();
}
}
- 测试结果
张三恭喜你,毕业了
=============
我是克隆的
李四恭喜你,毕业了
3.2 深克隆
创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
3.2.1 说明
graduates Student必须实现Serializable接口。
- UML

3.2.2 案例
- 测试类(其他类,同上)
public class testGraduates {
public static void main(String[] args) throws Exception {
graduates g1 = new graduates();
Student stu1 = new Student();
stu1.setName("张三");
g1.setStu(stu1);
g1.show();
System.out.println("=============");
//反序列化 进行深克隆,记得要让graduates Student都实现Serializable接口,否则报错
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\学习笔记包\\Java设计模式\\DP02设计模式\\oos.txt"));
oos.writeObject(g1);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\学习笔记包\\Java设计模式\\DP02设计模式\\oos.txt"));
graduates g2 = (graduates) ois.readObject();
Student stu2 = g2.getStu();
stu2.setName("李四");
g2.show();
}
}
- 测试结果
张三恭喜你,毕业了
=============
李四恭喜你,毕业了