原型模式
定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。简单地理解,其实就是当需要创建一个指定的对象时,我们刚好有一个这样的对象,但是又不能直接使用,我会clone一个一毛一样的新对象来使用;
场景
- 类初始化消耗资源较多。
- new 产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)
- 构造函数比较复杂。
- 循环体中生产大量对象时。
浅克隆
public interface IClonePrototype {
IClonePrototype copy();
}
public class ShallowPrototype implements IClonePrototype, Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public IClonePrototype copy() {
ShallowPrototype shallowPrototype = new ShallowPrototype();
shallowPrototype.setName(this.getName());
return shallowPrototype;
}
/**
* Object 里面的克隆方法
* @throws CloneNotSupportedException 异常
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// 测试
public static void main(String[] args) throws CloneNotSupportedException {
ShallowPrototype shallowPrototype1 = new ShallowPrototype();
shallowPrototype1.setName("LiDaShuang");
ShallowPrototype shallowPrototype2 = (ShallowPrototype) shallowPrototype1.copy();
System.out.println(shallowPrototype1);
System.out.println(shallowPrototype2);
// 得到实例的内存地址不同但是里面值的内存地址相同
System.out.println(shallowPrototype2.getName() == shallowPrototype1.getName()); // true 内存地址相同
}
复制代码
深克隆
public interface IClonePrototype {
IClonePrototype copy();
}
public class DeepPrototype implements IClonePrototype, Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public IClonePrototype copy() {
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (DeepPrototype) ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
// 测试
public static void main(String[] args) throws CloneNotSupportedException {
DeepPrototype deepPrototype1 = new DeepPrototype();
deepPrototype1.setName("LiDaShuang");
DeepPrototype deepPrototype2 = (DeepPrototype) deepPrototype1.copy();
System.out.println(deepPrototype1);
System.out.println(deepPrototype2);
System.out.println(deepPrototype1.getName() == deepPrototype2.getName()); // false 内存地址不相同
}
复制代码
总结
原型模式的本质就是clone,可以解决构建复杂对象的资源消耗问题,能再某些场景中提升构建对象的效率;还有一个重要的用途就是保护性拷贝,可以通过返回一个拷贝对象的形式,实现只读的限制。