原型模式指通过调用原型实例的Clone方法或其他手段来创建对象。
原型模式属于创建型设计模式,它以当前对象为原型(蓝本)来创建另一个新的对象,而无须知道创建的细节。原型模式在Java中通常使用Clone技术实现,在JavaScript中通常使用对象的原型属性实现。
原型模式的Java实现很简单,只需原型类实现Cloneable接口并覆写clone方法即可。Java中的复制分为浅复制和深复制。
- 浅复制:Java中的浅复制是通过实现Cloneable接口并覆写其Clone方法实现的。在浅复制的过程中,对象的基本数据类型的变量值会重新被复制和创建,而引用数据类型仍指向原对象的引用。也就是说,浅复制不复制对象的引用类型数据。
package cn.jaa.prototype_pattern; /** * @Author: Jaa * @Description: 浅复制 * @Date 2023/11/28 22:25 */ public class Computer implements Cloneable { private String cpu; private String memory; private String disk; public Computer(String cpu, String memory, String disk) { this.cpu = cpu; this.memory = memory; this.disk = disk; } @Override protected Object clone() { // 浅复制 try { return (Computer) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } @Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", memory='" + memory + '\'' + ", disk='" + disk + '\'' + '}'; } }
- 深复制:在深复制的过程中,不论是基本数据类型还是引用数据类型,都会被重新复制和创建。简而言之,深复制彻底复制了对象的数据(包括基本数据类型和引用数据类型),浅复制的复制却并不彻底(忽略了引用数据类型)。
package cn.jaa.prototype_pattern; /** * @Author: Jaa * @Description: 深复制 * @Date 2023/11/28 22:33 */ public class ComputerDetail implements Cloneable { private String cpu; private String memory; private Disk disk; public ComputerDetail(String cpu, String memory, Disk disk) { this.cpu = cpu; this.memory = memory; this.disk = disk; } @Override protected Object clone() { // 深复制 try { ComputerDetail computerDetail = (ComputerDetail) super.clone(); computerDetail.disk = (Disk) this.disk.clone(); // 引用对象深复制 return computerDetail; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } @Override public String toString() { return "ComputerDetail{" + "cpu='" + cpu + '\'' + ", memory='" + memory + '\'' + ", disk=" + disk + '}'; } }
package cn.jaa.prototype_pattern; /** * @Author: Jaa * @Description: * @Date 2023/11/28 22:34 */ public class Disk implements Cloneable { private String ssd; private String hhd; public Disk(String ssd, String hhd) { this.ssd = ssd; this.hhd = hhd; } @Override protected Object clone() { // 应用对象深复制 try { return (Disk) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } @Override public String toString() { return "Disk{" + "ssd='" + ssd + '\'' + ", hhd='" + hhd + '\'' + '}'; } }
浅复制、深复制测试:
package cn.jaa.prototype_pattern; import lombok.extern.slf4j.Slf4j; /** * @Author: Jaa * @Description: simple and deep clone test * @Date 2023/11/28 22:41 */ @Slf4j public class PrototypeDemoTest { public static void main(String[] args) { // 浅复制 Computer computer = new Computer("16core", "16G", "1TB"); log.info("before simple clone: " + computer.toString()); Computer computerClone = (Computer) computer.clone(); log.info("after simple clone: " + computerClone.toString()); // 深复制 Disk disk = new Disk("256G", "1TB"); ComputerDetail computerDetail = new ComputerDetail("16core", "16G", disk); log.info("before deep clone: " + computerDetail.toString()); ComputerDetail computerDetailClone = (ComputerDetail) computerDetail.clone(); log.info("after deep clone: " + computerDetailClone.toString()); } }
运行结果: