原型模式 与 建造者模式(1)

简介: 原型模式 与 建造者模式(1)

一、原型模式


原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,属于创建型模式。


原型模式的核心在于拷贝原型对象。以系统中已存在的一个对象为原型,直接基于内存二进制流进行拷贝,无需再经历耗时的对象初始化过程(不调用构造函数),性能提升许多。当兑现的构建过程比较耗时时,可以利用当前系统中已存在的对象作为原型,对其进行克隆(一般是基于二进制流的复制),躲避初始化过程,使得新对象的创建时间大大减少。下面,我们来看看原型模式类结构图。



image.png


从UML图中,我们可以看到,原型模式,主要包含三个角色:


客户(Client):客户类提出创建对象的请求。

抽象原型(Prototype):规定拷贝接口。

具体原型(Concrete Prototype):被拷贝的对象。

注:对不通过new关键字,而是通过对象拷贝来实现创建对象的模式就称作原型模式。


原型模式的应用场景

你一定遇到过大篇幅getter、setter赋值的场景。例如这样的代码:


@Data
public class ExamPaper{
   private String examinationPaperId;//试卷主键
   private String leavTime;//剩余时间
   private String organizationId;//单位主键
   private String id;//考试主键
   private String examRoomId;//考场主键
   private String userId;//用户主键
   private String specialtyCode;//专业代码
   private String postionCode;//报考岗位
   private String gradeCode;//报考等级
   private String examStartTime;//考试开始时间
   private String examEndTime;//考试结束时间
   private String singleSelectionImpCount;//单选选题重要数量
   private String multiSelectionImpCount;//多选题重要数量
   private String judgementImpCount;//判断题重要数量
   private String examTime;//考试时长
   private String fullScore;//总分
   private String passScore;//及格分
   private String userName;//学员姓名
   private String score;//考试得分
   private String resut;//是否及格
   private String singleOkCount;//单选题答对数量
   private String multiOkCount;//多选题答对数量
   private String judgementOkCount;//判断题答对数量
   public ExamPaper copy(){
      ExamPaper examPaper = new ExamPaper();
      //剩余时间
      examPaper.setLeavTime(this.getLeavTime());
      //单位主键
      examPaper.setOrganizationId(this.getOrganizationId());
      //考试主键
      examPaper.setId(this.getId());
      //用户主键
      examPaper.setUserId(this.getUserId());
      //专业
      examPaper.setSpecialtyCode(this.getSpecialtyCode());
      //岗位
      examPaper.setPostionCode(this.getPostionCode());
      //等级
      examPaper.setGradeCode(this.getGradeCode());
      //考试开始时间
      examPaper.setExamStartTime(this.getExamStartTime());
      //考试结束时间
      examPaper.setExamEndTime(this.getExamEndTime());
      //单选题重要数量
      examPaper.setSingleSelectionImpCount(this.getSingleSelectionImpCount());
      //多选题重要数量
      examPaper.setMultiSelectionImpCount(this.getMultiSelectionImpCount());
      //判断题重要数量
      examPaper.setJudgementImpCount(this.getJudgementImpCount());
      //考试时间
      examPaper.setExamTime(this.getExamTime());
      //总分
      examPaper.setFullScore(this.getFullScore());
      //及格分
      examPaper.setPassScore(this.getPassScore());
      //学员姓名
      examPaper.setUserName(this.getUserName());
      //分数
      examPaper.setScore(this.getScore());
      //单选答对数量
      examPaper.setSingleOkCount(this.getSingleOkCount());
      //多选答对数量
      examPaper.setMultiOkCount(this.getMultiOkCount());
      //判断答对数量
      examPaper.setJudgementOkCount(this.getJudgementOkCount());
      return examPaper;
   }
   @Override
   public String toString() {
      return "ExamPaper{" +
              "examinationPaperId='" + examinationPaperId + '\'' +
              ", leavTime='" + leavTime + '\'' +
              ", organizationId='" + organizationId + '\'' +
              ", id='" + id + '\'' +
              ", examRoomId='" + examRoomId + '\'' +
              ", userId='" + userId + '\'' +
              ", specialtyCode='" + specialtyCode + '\'' +
              ", postionCode='" + postionCode + '\'' +
              ", gradeCode='" + gradeCode + '\'' +
              ", examStartTime='" + examStartTime + '\'' +
              ", examEndTime='" + examEndTime + '\'' +
              ", singleSelectionImpCount='" + singleSelectionImpCount + '\'' +
              ", multiSelectionImpCount='" + multiSelectionImpCount + '\'' +
              ", judgementImpCount='" + judgementImpCount + '\'' +
              ", examTime='" + examTime + '\'' +
              ", fullScore='" + fullScore + '\'' +
              ", passScore='" + passScore + '\'' +
              ", userName='" + userName + '\'' +
              ", score='" + score + '\'' +
              ", resut='" + resut + '\'' +
              ", singleOkCount='" + singleOkCount + '\'' +
              ", multiOkCount='" + multiOkCount + '\'' +
              ", judgementOkCount='" + judgementOkCount + '\'' +
              '}';
   }
}


代码非常工整,命名非常规范,注释也写的很全面,其实这就是原型模式的需求场景。但是,上述代码属于纯体力劳动。那原型模式,能帮助我们解决这样的问题。


原型模式主要适用于以下场景:

1、类初始化消化资源较多

2、new 产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)

3、构造函数比较复杂

4、循环体中生产大量的对象时。

在Spring中,原型模式应用得非常广泛。例如 scope = “prototype”,在我们经常用的JSON。parseObject()也是一种原型模式。


原型模式的通用写法


一个标准的原型模式代码,应该是这样设计的,先创建原型IPrototype接口:


public interface IPrototype<T> {
    T clone();
}


创建具体需要克隆的对象ConcretePrototype


public class ConcretePrototype implements IPrototype {
    private int age;
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public ConcretePrototype clone() {
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(this.age);
        concretePrototype.setName(this.name);
        return concretePrototype;
    }
    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
目录
相关文章
|
人工智能 语音技术 Android开发
|
9月前
|
人工智能 自然语言处理 并行计算
Chitu:清华核弹级开源!推理引擎3倍提速+50%省卡,国产芯片告别英伟达绑架
Chitu(赤兔)是清华大学与清程极智联合开源的高性能大模型推理引擎,支持多硬件适配,显著提升推理效率,适用于金融、医疗、交通等多个领域。
854 10
Chitu:清华核弹级开源!推理引擎3倍提速+50%省卡,国产芯片告别英伟达绑架
|
12月前
|
Kubernetes Ubuntu 网络安全
ubuntu使用kubeadm搭建k8s集群
通过以上步骤,您可以在 Ubuntu 系统上使用 kubeadm 成功搭建一个 Kubernetes 集群。本文详细介绍了从环境准备、安装 Kubernetes 组件、初始化集群到管理和使用集群的完整过程,希望对您有所帮助。在实际应用中,您可以根据具体需求调整配置,进一步优化集群性能和安全性。
1098 13
|
SQL jenkins 持续交付
一篇文章掌握 FTP 和本地文件系统的桥梁 - CurlFtpFS
一篇文章掌握 FTP 和本地文件系统的桥梁 - CurlFtpFS
|
数据采集 存储 分布式计算
ClickHouse大规模数据导入优化:批处理与并行处理
【10月更文挑战第27天】在数据驱动的时代,高效的数据导入和处理能力是企业竞争力的重要组成部分。作为一位数据工程师,我在实际工作中经常遇到需要将大量数据导入ClickHouse的需求。ClickHouse是一款高性能的列式数据库系统,非常适合进行大规模数据的分析和查询。然而,如何优化ClickHouse的数据导入过程,提高导入的效率和速度,是我们面临的一个重要挑战。本文将从我个人的角度出发,详细介绍如何通过批处理、并行处理和数据预处理等技术优化ClickHouse的数据导入过程。
1284 0
|
存储 关系型数据库 MySQL
【mysql】文本字符串类型
【mysql】文本字符串类型
4557 1
【mysql】文本字符串类型
【qt】纯代码界面设计
【qt】纯代码界面设计
482 2
|
Java 应用服务中间件 nginx
idea打war包时,JDK版本的问题解决方式
idea打war包时,JDK版本的问题解决方式
|
缓存 Java Maven
深入解析Google Guava库与Spring Retry重试框架
深入解析Google Guava库与Spring Retry重试框架
idea+git实现提交自动去除无用import以及格式化代码
idea+git实现提交自动去除无用import以及格式化代码
901 0