目录
1.核心本质
1.对象的克隆
2.减少对象创建时间
3.保护对象的复杂性
4.动态配置属性
2.适用场景
对象初始化成本高,需要频繁创建的情况
当一个对象的创建成本比较高,而你又需要频繁地创建这个对象时,使用原型模式可以通过复制现有实例来提高效率,避免每次都进行昂贵的初始化操作。
需要避免构造函数复杂化的情况
如果某个对象的构造函数或者初始化过程比较复杂,而且需要创建多个相似对象,使用原型模式可以简化对象的创建过程,通过复制现有对象来避免复杂的初始化逻辑。
保护性拷贝的需求
当需要创建一个对象,这个对象的数据需要保护不被外部修改,同时又需要在某些时候复制该对象并进行修改时,原型模式可以帮助实现这种保护性拷贝。
动态配置对象的场景
当系统需要动态地配置对象,根据用户或者环境的不同配置创建不同的对象时,原型模式可以作为一种简洁的创建对象方式。
需要避免继承的场景
当类之间的区别仅在于其初始化数据时,可以使用原型模式避免创建多个相似的子类。
3.浅拷贝和深拷贝的区别
浅拷贝:引用复制,引用对象复制引用地址(旧对象或者拷贝对象修改引用对象的值,另外一个对象的对应值也会修改),基础类型复制值。
深拷贝:全新的对象。
4.代码举例
1.地址类
import java.io.Serializable;
/**
* 不使用序列化或者反序列化,不用实现Serializable接口
*/
public class Adress implements Cloneable, Serializable {
String city;
public Adress(String city){
this.city = city;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Adress{" +
"city='" + city + '\'' +
'}';
}
public Adress clone() throws CloneNotSupportedException {
return (Adress) super.clone();
}
}
2.人员信息类
import java.io.*;
/**
* 不使用序列化或者反序列化,不用实现Serializable接口
*/
public class Person implements Cloneable,Serializable{
String name;
int age;
Adress adress;
public Person(String name, int age, Adress adress) {
this.name = name;
this.age = age;
this.adress = adress;
}
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 Adress getAdress() {
return adress;
}
public void setAdress(Adress adress) {
this.adress = adress;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", adress=" + adress +
'}';
}
/**
* 浅拷贝 ---引用对象复制引用地址,基础类型复制值
* return (Person)super.clone();
* 深拷贝1 ---重写所有引用对象clone方法
* Person person = (Person) super.clone();
* person.adress=(Adress) this.adress.clone();
* return person;
*/
public Person clone() {
//序列化
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(bos);
objectOutputStream.writeObject(this);
objectOutputStream.flush();
objectOutputStream.close();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
Person person = (Person) objectInputStream.readObject();
objectInputStream.close();
return person;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
3.测试类
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("张三",20,new Adress("北京"));
Person person2 = person1.clone();
person2.getAdress().setCity("上海");
System.out.println(person1.toString());
System.out.println(person2.toString());
}
}