一、定义
主要作用:主要用来对象的复制。通过第一次new的实例化的对象进行克隆,之后需要实例化对象时,直接克隆实例化对象变行。
二、UML图

三、原型模式的用法和注意点
1)用法
原型模式的核心类(接口)是:Prototype类(接口),在Java中Prototype需要具备以下的条件:
1、实现Cloneable接口,Java中的Cloneable是一个标志性接口,接口中不存在任何的方法。目的是为了告诉Jvm,实现了这个接口就可以被克隆,否则在运行的时候回抛出CloneNotSupportedException异常。
2、clone方法的作用是对象的拷贝,重写Object类的clone()方法,原因是因为Object类中的clone()方法是protected访问权限。有些类无法进行访问,将其改为public访问权限变行。
2)注意点
1、clone()方法具有两种拷贝,一种是浅拷贝,一种是深拷贝。浅拷贝,拷贝的只是对象中的基本数据类型和其包装类还有String。想要深拷贝,必须要将对象中的数组,容器,对象进行另外拷贝。
2、原型模式复制对象不会调用类的构造方法,但是你进行new初始化一定是通过构造方法的。为什么原型模型复制对象不会调用类的构造方法呢?因为对象的复制通过Object类中clone方法进行,clone方法是直接在内存中进行复制数据,因此不会调用到类的构造方法。因此clone方法也会直接无视构造方法的访问权限,也因此和单例模式是有冲突的。
四、实例
创建个人简历
简历的接口:
package com.golf.Prototype;
public interface Resume {
public void show();
}
具体简历的实现(浅拷贝):
package com.golf.Prototype;
import java.util.ArrayList;
public class PersonResume implements Cloneable,Resume {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public Object clone() {
PersonResume personResume=null;
try {
personResume = (PersonResume) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return personResume;
}
@Override
public void show() {
System.out.println(name+age);
}
}
具体简历的实现(深拷贝):
package com.golf.Prototype;
import java.util.ArrayList;
public class PersonResume2 implements Cloneable,Resume{
private String name;
private String age;
private ArrayList arrayList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public Object clone() {
PersonResume2 personResume2=null;
personResume2 = (PersonResume2) super.clone(); //拷贝基本数据类型和String
personResume2.arrayList = (ArrayList) this.arrayList.clone();//拷贝对象
return personResume2;
}
@Override
public void show() {
System.out.println(name+age);
}
}
客户端:
package com.golf.Prototype;
public class Client {
public static void main(String[] args) {
PersonResume personResume = new PersonResume();
personResume.setName("白");
personResume.setAge("23");
personResume.show();
PersonResume personResume1 = (PersonResume) personResume.clone();
personResume1.setName("黑");
personResume1.setAge("32");
personResume1.show();
}
}
五、原型模式的优缺点