【3】原型Prototype(创建型)

说明

用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象;
克隆羊问题,通过 Object 类的 clone 实现实例的复制;
Spring 的 bean 创建,当 bean 类型为原型时,每次都会生成一个 bean,scope=“prototype”;
原型模式的浅拷贝和深拷贝。深拷贝实现方式:序列化,通过文件流实现;重写引用类型的 clone 方法;

优缺点

  • 优点

通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,用 clone 创建对象可以极大的节约时间;

  • 缺点

如果需要对老的类实现拷贝,则需要修改源码,违反了 ocp 原则;

示例

package com.firechou.prototype;

import lombok.Data;

/**
 * @Author firechou
 * @Date 2023/6/2 15:12
 * @Version 1.0
 * @Description 简历类
 */
@Data
public class Resume implements Cloneable {
    // 需要实现Cloneable接口,否则即使实现了clone方法,运行时会报错
    /**
     * 用户名
     */
    private String userName;
    /**
     * 工作经历
     */
    private WorkExpression workExpression;

    @Override
    protected Resume clone() throws CloneNotSupportedException {
        Resume resume = (Resume)super.clone();
        // 深拷贝实现
//        resume.workExpression = workExpression.clone();
        resume.workExpression = workExpression.clone();
        return resume;

    }
}

package com.firechou.prototype;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @Author firechou
 * @Date 2023/6/2 15:13
 * @Version 1.0
 * @Description 工作经历
 */
@AllArgsConstructor
@Data
public class WorkExpression implements Cloneable {
    /**
     * 公司名
     */
    private String companyName;
    /**
     * 工作年数
     */
    private int workYears;

    @Override
    protected WorkExpression clone() throws CloneNotSupportedException {
        return (WorkExpression)super.clone();
    }
}

package com.firechou.prototype;

/**
 * @Author firechou
 * @Date 2023/6/2 15:14
 * @Version 1.0
 * @Description 测试入口
 */
public class Client {
    public static void main(String[] args) throws Exception {
        Resume resume = new Resume();
        resume.setUserName("Jay");
        WorkExpression workExpression = new WorkExpression("斗鱼", 3);
        resume.setWorkExpression(workExpression);

        // 原型实现
        Resume resume2 = resume.clone();
        resume2.getWorkExpression().setCompanyName("找钢");

        System.out.println(resume);
        System.out.println(resume2);
        /**
         * Resume(userName=Jay, workExpression=WorkExpression(companyName=斗鱼, workYears=3))
         * Resume(userName=Jay, workExpression=WorkExpression(companyName=找钢, workYears=3))
         */
    }
}

你可能感兴趣的:(#,设计模式,原型模式,java,设计模式)