定义
优点
Java⾃带的原型模式基于内存⼆进制流的复制,在性能上⽐直接new⼀个对象更加优良。
可以使⽤深克隆⽅式保存对象的状态,使⽤原型模式将对象复制⼀份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使⽤(例如恢复到历史某⼀状态),可辅助实现撤销操作。
缺点
需要为每⼀个类都配置⼀个 clone ⽅法
clone ⽅法位于类的内部,当对已有类进⾏改造的时候,需要修改代码,违背了开闭原则。
当实现深克隆时,需要编写较为复杂的代码,⽽且当对象之间存在多重嵌套引⽤时,为了实现深克隆,每⼀层对象对应的类都必须⽀持深克隆,实现起来会⽐较麻烦。因此,深克隆、浅克隆需要运⽤得当。
原型模式实现对象克隆有两种形式:浅克隆与深克隆
代码实现
浅克隆
浅克隆:创建⼀个新对象,新对象的属性和原来对象完全相同,对于⾮基本类型属性,仍指向原有属性所指向的对象的内存地址。
汽车类:
public class Car { //定义车的车牌号属性 public String number; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }
员工类:
//被复制的对象需要实现Clonable接⼝与clone()⽅法 public class Employee implements Cloneable{ private String name; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } //重写clone方法 @Override protected Object clone() throws CloneNotSupportedException { System.out.println("正在复制Employee对象"); return super.clone(); } }
应用入口:
public class App { public static void main(String[] args) throws CloneNotSupportedException { Employee king = new Employee(); king.setName("King"); Car car = new Car(); car.setNumber("FBW 381"); // 将king和cat对象进行绑定 king.setCar(car); // 进行clone操作 Employee cloneKing = (Employee) king.clone(); // 结果验证 System.out.println("King == CloneKing:" + (king == cloneKing)); System.out.println("King.car == CloneKing.car:" + (king.getCar() == cloneKing.getCar())); } }
输出结果:
正在复制Employee对象 King == CloneKing:false //通过clone方法在内存中创建了两个不同的对象,所以为false King.car == CloneKing.car:true //都指向了相同的一个car对象,所以为true
深克隆
深克隆:创建⼀个新对象,属性中引⽤的其他对象也会被克隆,不再指向原有对象地址。
Car代码完全相同,省略
基于Json实现对象深度Clone,不再需要实现Clonable接⼝与clone()⽅法
public class Employee { private String name; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } //基于JSON实现深度序列化 public Employee deepClone(){ Gson gson = new Gson(); String json = gson.toJson(this); System.out.println(json); Employee cloneObject = gson.fromJson(json,Employee.class); return cloneObject; } }
应用入口:
public class App { public static void main(String[] args) throws CloneNotSupportedException { Employee king = new Employee(); king.setName("King"); Car car = new Car(); car.setNumber("FBW 381"); // 将king和cat对象进行绑定 king.setCar(car); // 进行clone操作 Employee cloneKing = (Employee) king.deepClone(); System.out.println("King == CloneKing:" + (king == cloneKing)); System.out.println("King.car == CloneKing.car:" + (king.getCar() == cloneKing.getCar())); } }
输出结果:
{"name":"King","car":{"number":"FBW 381"}} King == CloneKing:false King.car == CloneKing.car:false //在内存中是完全独立切割开的
应用场景
对象之间相同或相似,即只是个别的⼏个属性不同的时候。
创建对象成本较⼤,例如初始化时间⻓,占⽤CPU太多,或者占⽤⽹络资源太多等,需要优化资源。
创建⼀个对象需要繁琐的数据准备或访问权限等,需要提⾼性能或者提⾼安全性。
系统中⼤量使⽤该类对象,且各个调⽤者都需要给它的属性重新赋值。