Java设计模式–原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone()
相关类图:
浅拷贝以及深拷贝
浅拷贝
浅拷贝的整个过程就是,创建一个新的对象,然后新对象的每个值都是由原对象的值,通过 = 进行赋值
基本数据类型是值赋值;非基本的就是引用赋值
public class Person implements Cloneable {
private String name;
private int age;
private Phone phone; //引用类型
public Person(String name, int age, String role, Phone phone){
this.age = age;
this.name = name;
this.role = role;
this.phone = phone;
}
//浅拷贝 引用类型指向同个对象
@Override
protected Object clone() {
Person person = null;
try{
person = (Person) super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return person;
}
}
深拷贝
深拷贝,就是要创建一个全新的对象,新的对象内部所有的成员也都是全新的,只是初始化的值已经由被拷贝的对象确定了而已
1.通过对每个复杂成员变量重写clone()方法来实现
缺点,就是当一个类的成员变量很多或者成员变量层次很深的时候,采用clone()方法会显得很繁琐。
Phone.java
public class Phone implements Cloneable{
private String name;
public Phone(String name){
this.name = name;
}
@Override
protected Object clone() {
Object object = null;
try {
object = super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return object;
}
}
Person.java
public class Person implements Cloneable {
private String name;
private int age;
private Phone phone;
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected String role;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", phone=" + phone +
", role='" + role + '\'' +
'}';
}
public Person(String name, int age, String role, Phone phone){
this.age = age;
this.name = name;
this.role = role;
this.phone = phone;
}
@Override
protected Object clone() {
Object object = null;
Person person = null;
try{
object = super.clone();
person = (Person) object;
person.phone = (Phone) person.getPhone().clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return person;
}
}
1.通过序列化克隆对象(推荐使用)
Address.java
public class Address implements Serializable {
private String addrInfo;
public Address(String addrInfo) {
this.addrInfo = addrInfo;
}
public String getAddrInfo() {
return addrInfo;
}
public void setAddrInfo(String addrInfo) {
this.addrInfo = addrInfo;
}
}
Man.java
public class Man implements Serializable {
private String name;
public String getName() {
return name;
}
public Man(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
private Address addr;
public Address getAddr() {
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Man{" +
"name='" + name + '\'' +
", addr=" + addr +
'}';
}
}
Demo.java
public class Demo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Man man = new Man("huang");
man.setAddr(new Address("富人区"));
System.out.println(man);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(man);
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
Man poor = (Man) ois.readObject();
System.out.println(poor);
poor.getAddr().setAddrInfo("穷人区");
System.out.println(poor);
}
}