1.概念
原型模式(Prototype Pattern)是指定原型实例指定创建对象的种类,并且拷贝这些原型创建新的对象
调用者不需要知道任何创建细节,不调用构造函数
属于创建型模式
2.适用场景
1.类初始化消耗资源较多
2.new一个对象需要非常繁琐的过程,如:数据准备/访问权限等
3.构造函数比较复杂
4.循环体中产生大量对象时
例如:
BeanUtils.copy属于原型模式的应用
3.浅克隆
1.克隆对象与源对象的非同一对象,即内存中地址不同
2.克隆对象与源对象的属性值完全相同
3.克隆对象对其它对象的引用,任然指向源对象中的地址,即只克隆最外层对象
/**
* Description:原型接口
*
* @date 2019-05-06 20:32
*/
public interface Prototype {
Prototype clone();
}
/**
* Description:学生类
*
* @date 2019-05-06 20:35
*/
public class Student implements Prototype{
//姓名
private String name;
//年龄
private int age;
//爱好
private List hobbies;
@Override
public Prototype clone() {
Student student = new Student();
student.setName(this.name);
student.setAge(this.age);
student.setHobbies(this.hobbies);
return student;
}
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 List getHobbies() {
return hobbies;
}
public void setHobbies(List hobbies) {
this.hobbies = hobbies;
}
}
/**
* Description:教师类
*
* @date 2019-05-06 20:35
*/
public class Teacher implements Prototype{
//姓名
private String name;
//年龄
private int age;
//爱好
private List hobbies;
@Override
public Prototype clone() {
Teacher teacher = new Teacher();
teacher.setName(this.name);
teacher.setAge(this.age);
teacher.setHobbies(this.hobbies);
return teacher;
}
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 List getHobbies() {
return hobbies;
}
public void setHobbies(List hobbies) {
this.hobbies = hobbies;
}
}
/**
* Description:克隆客户端
*
* @date 2019-05-06 20:52
*/
public class Client {
public Prototype startClone(Prototype source){
return source.clone();
}
}
/**
* Description:测试类
*
* @date 2019-05-06 20:42
*/
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("张无忌");
s1.setAge(18);
s1.setHobbies(Lists.newArrayList("开车"));
Client client = new Client();
Student s2 = (Student)client.startClone(s1);
System.out.println("s1 == s2 "+(s1 == s2));
System.out.println("s1.hobbies == s2.hobbies "+(s1.getHobbies() == s2.getHobbies()));
}
}
4.深克隆
1.克隆对象与源对象的非同一对象,即内存中地址不同
2.克隆对象与源对象的属性值完全相同
3.克隆对象对其它对象的引用也不相同
可能会和单例模式冲突
/**
* Description:学生类
*
* @date 2019-05-06 20:35
*/
public class Student implements Serializable,Cloneable {
//姓名
private String name;
//年龄
private int age;
//爱好
private List hobbies;
public Student clone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Student student = (Student) ois.readObject();
student.setHobbies(Lists.newArrayList("坐车"));//此处不设置,将为空
return student;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
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 List getHobbies() {
return hobbies;
}
public void setHobbies(List hobbies) {
this.hobbies = hobbies;
}
}
/**
* Description:测试类
*
* @date 2019-05-06 20:42
*/
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("张无忌");
s1.setAge(18);
s1.setHobbies(Lists.newArrayList("开车"));
Student s2 = s1.clone();
System.out.println("s1 == s2 "+(s1 == s2));
System.out.println("s1.hobbies == s2.hobbies "+(s1.getHobbies() == s2.getHobbies()));
}
}