> 文档中心 > 06-设计模式——原型模式

06-设计模式——原型模式


设计模式——原型模式

知识点:

  1. Cloneable接口/Pbject#clone方法 详解
  2. 浅拷贝/深拷贝
  3. 序列化机制实现深拷贝

模式定义:

指原型实例指定创建对象的种类,并且通过拷贝(复制)这些原型创建新的对象

06-设计模式——原型模式

应用场景:

当代码不应该依赖于需要复制的对象的具体类时,请使用Prototype模式

优点:

  1. 可以不耦合具体类的情况下克隆对象
  2. 避免重复的初始化代码
  3. 更方便的构建复杂对象

package com.example.designpatterns.prototype;import cn.hutool.Hutool;import cn.hutool.core.util.HashUtil;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.io.*;/** * @program: DesignPatterns * @description: 原型模式 * @author: Coder_Pan * @create: 2022-04-13 11:12 **/public class PrototypeTest {    public static void main(String[] args) throws CloneNotSupportedException { BaseInfo baseInfo = new BaseInfo("ssss"); Product product = new Product("part1", "part2", 3, 4, 5,baseInfo); Product clone = product.clone(); System.out.println("克隆出来的对象与源对象不相等"); System.out.println(product == clone); System.out.println(product); System.out.println(clone); product.getBaseInfo().setCompanyName("pppp"); System.out.println(product); System.out.println("依旧存在关联,这样是不对的,需要通过两次拷贝,对引用对象也进行拷贝才正确"); System.out.println(clone);    }}@Dataclass BaseInfo implements Cloneable,Serializable{    /**     * 实现序列化,如果需要进行持久化操作,必须加版本号     */    private static final long serialVersionUID = 42L;    private String companyName;    public BaseInfo(String ssss) { this.companyName = ssss;    }    @Override    protected BaseInfo clone() throws CloneNotSupportedException { return ((BaseInfo) super.clone());    }    @Override    public String toString() { return super.hashCode() + "BaseInfo{" +  "companyName='" + companyName + '\'' +  '}';    }}/** * 定义产品实例 */@Data@AllArgsConstructor@NoArgsConstructorclass Product implements Cloneable,Serializable{    /**     * 实现序列化,如果需要进行持久化操作,必须加版本号     */    private static final long serialVersionUID = 42L;    private String part1;    private String part2;    private Integer part3;    private Integer part4;    private Integer part5;    private BaseInfo baseInfo;    /**     * V1 - 使用Java中的clone方式实现原型模式     * @return     * @throws CloneNotSupportedException     */    @Override    protected Product clone() throws CloneNotSupportedException { //本对象拷贝 Product clone = (Product) super.clone(); //本对象中使用到的对象的拷贝 == > 深拷贝 BaseInfo clone1 = this.baseInfo.clone(); clone.setBaseInfo(clone1); return clone;    }    /**     * V2 - 通过Java序列化的方式进行拷贝,实现原型模式     * 若想使用序列化操作,则在涉及到拷贝的每个class上都应实现Serializable     * 这个方式由CPU来执行,比较消耗性能,速度比较慢     *     * 不推荐使用.....     * @return     * @throws CloneNotSupportedException     */    protected Product clone1() throws CloneNotSupportedException { //1、定义输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(  ); try {     ObjectOutputStream oos = new ObjectOutputStream(baos);     oos.writeObject( this ); } catch (IOException e) {     e.printStackTrace(); } //拿到输入流对象 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray()); //从内存中恢复数据 try {     ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);     Product product = (Product) ois.readObject();     return product;     //这里完成深拷贝 } catch (IOException e) {     e.printStackTrace(); } catch (ClassNotFoundException e) {     e.printStackTrace(); } return null;    }    @Override    public String toString() { return super.hashCode() +  "Product{" +  "part1='" + part1 + '\'' +  ", part2='" + part2 + '\'' +  ", part3=" + part3 +  ", part4=" + part4 +  ", part5=" + part5 +  ", baseInfo=" + baseInfo +  '}';    }}