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

设计模式——原型模式

知识点:

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

模式定义:

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

LuvR8s.png

应用场景:

当代码不应该依赖于需要复制的对象的具体类时,请使用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);
    }
}


@Data
class 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
@NoArgsConstructor
class 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 +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值