原型模式就是用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象 好比我要生产10000台电脑,正常需要一步步组装CPU、GPU等组件,而原型模式,就是在已经组装好的电脑,通过复制(克隆)来形成新的电脑
原型类要实现 Cloneable 接口然后重写clone方法即可
原型模式的克隆分为浅克隆和深克隆。 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
原型:HightComputer{id=0, branch=‘huawei’, cpu=CPU{id=0, basicFrequency=‘1.8GHZ’, type=‘i5’, coreNum=‘4核’, threadNum=‘8线程’}} 克隆:HightComputer{id=0, branch=‘huawei’, cpu=CPU{id=0, basicFrequency=‘1.8GHZ’, type=‘i5’, coreNum=‘4核’, threadNum=‘8线程’}} 输出结果如上所示,浅克隆对非基本类型属性(CPU),仍指向原来的内存地址 即改变原型CPU参数,克隆后的对象也一样会改变(前后都变成i5了),应该保持克隆后的对象为i7的
深克隆,则需要在clone方法中对克隆后的实例对象修改其非基本类型数据,使其与原引用断开。
public class HightComputer implements Cloneable { private int id; private String branch; private CPU cpu; //get、set方法 @Override protected HightComputer clone() throws CloneNotSupportedException { HightComputer clone = (HightComputer) super.clone(); CPU cpu = clone.getCpu().clone(); clone.setCpu(cpu); return clone; } @Test public void main1() throws CloneNotSupportedException { CPU cpu = new CPU("1.8GHZ", "i7", "4核", "8线程"); HightComputer hightComputer = new HightComputer(); hightComputer.setBranch("huawei"); hightComputer.setCpu(cpu); hightComputer.setId(0); for (int i = 1; i < 2; i++) { HightComputer computer = hightComputer.clone(); hightComputer.getCpu().setType("i5"); System.out.println("原型:" + hightComputer); System.out.println("克隆:" + computer); } }原型:HightComputer{id=0, branch=‘huawei’, cpu=CPU{id=0, basicFrequency=‘1.8GHZ’, type=‘i5’, coreNum=‘4核’, threadNum=‘8线程’}} 克隆:HightComputer{id=0, branch=‘huawei’, cpu=CPU{id=0, basicFrequency=‘1.8GHZ’, type=‘i7’, coreNum=‘4核’, threadNum=‘8线程’}} 上述输出可见,克隆后的对象保持原型的属性参数。
Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。 如果对象的初始化较长,或占用资源太多,也就是创建对象的成本较大,使用原型模式效率会高点
从实现也可以指定,原型模式需要每个实例(包括其非基本类型属性)均要实现Cloneable接口和clone方法,深克隆的时候,还要修改clone方法的实现,有一定复杂。