设计模式-原型模式
1 介绍
原型模式的思想:将一个对象作为原型,对其进行复制、克隆,产生一个与原对象类似的新对象。
- 浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建;引用类型,指向的还是原对象所指向的,可以根据hasCode判断。
- 深拷贝:将一个对象复制后,无论是基本数据类型或者是引用类型的变量,都是重新创建。
- 被拷贝的对象需要实现Cloneable接口。
简单的说,深拷贝是创建全新的对象,浅对象复制的不彻底。
注意:被拷贝的对象类,都要继承序列化接口Serializable
2 示例
- AbstractCloneable 继承Cloneable, 实现浅拷贝与深拷贝的逻辑
public abstract class AbstractCloneable implements Cloneable, Serializable {
/**
* 浅拷贝
*
* @return
* @throws CloneNotSupportedException
*/
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* 深度拷贝
*/
public Object deepClone() throws IOException, ClassNotFoundException {
/**
* 写入当前对象的二进制流
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/**
* 读出二进制流产生的对象
*/
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
- Car 继承 AbstractCloneable
public class Car extends AbstractCloneable {
public Car(String name, String color, Person person) {
this.name = name;
this.color = color;
this.person = person;
}
private String name;
private String color;
private Person person;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", person.hashCode='" + person.hashCode() + '\'' +
'}';
}
}
- class Person
public class Person implements Serializable {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- PrototypeCloneFactory 工厂方法
public class PrototypeCloneFactory {
/**
* 浅拷贝
* 反射执行
*/
public <T> T clone(T clone) {
try {
if(clone instanceof AbstractCloneable) {
Class aClass = clone.getClass();
Method cloneMethod = aClass.getMethod("clone");
return (T)cloneMethod.invoke(clone);
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 深拷贝
* 反射执行
*/
public <T> T deepClone(T clone) {
try {
if(clone instanceof AbstractCloneable) {
Class aClass = clone.getClass();
Method cloneMethod = aClass.getMethod("deepClone");
return (T)cloneMethod.invoke(clone);
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
- client
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person("person");
Car car = new Car("轿车", "red", person);
PrototypeCloneFactory prototypeModel = new PrototypeCloneFactory();
// 浅拷贝
Car cloneCar = prototypeModel.clone(car);
// 深度拷贝
Car deepCloneCar = prototypeModel.deepClone(car);
System.out.println(car.toString());
System.out.println(cloneCar.toString());
System.out.println(deepCloneCar.toString());
}
}
输出
# 被拷贝对象
Car{name='轿车', color='red', person.hashCode='1554874502'}
# 浅拷贝对象
Car{name='轿车', color='red', person.hashCode='1554874502'}
# 深拷贝对象
Car{name='轿车', color='red', person.hashCode='1072408673'}
结论
浅拷贝复制的不彻底,引用类型指向原对象的引用(地址);深拷贝复制的彻底,成员变量,基本类型、应用类型均创建全新的对象。