原型模式指通过调用原型实例的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;}@Overrideprotected Object clone() { // 浅复制try {return (Computer) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}@Overridepublic 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;}@Overrideprotected Object clone() { // 深复制try {ComputerDetail computerDetail = (ComputerDetail) super.clone();computerDetail.disk = (Disk) this.disk.clone(); // 引用对象深复制return computerDetail;} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}@Overridepublic 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;}@Overrideprotected Object clone() { // 应用对象深复制try {return (Disk) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}@Overridepublic 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());} }
运行结果: