一、原型模式(ProtoType)

作用:用原型实例指定创建对象的种类,并且通过拷贝这些原创新的对象

白话解释:用于创建重复的对象,同时有能保证性能(这种类型的设计模式属于创建型设计模式,他提供了一种创建对象的最佳方式)

主要解决:在运行期间建立和删除原型

使用场景:

  1. 当一个系统应该独立于他的产品创建,构成和表达时
  2. 当要实例化的类是在运行时时刻指定时,例如,通过动态装载
  3. 为了避免创建一个与产品类层次平行的工厂类层次时
  4. 当一个类的实例只能有几个不同状态组合中的一种时
  5. 建立相对应数目的原型并克隆他们可能比每次合适的状态手工实例化该类更方便一些
  6. 资源优化场景
  7. 类初始化需要消耗非常多的资源,这个资源包括数据、硬件资源等
  8. 性能和安全要求的场景
  9. 通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
  10. 一个对象多个修改者的场景
  11. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式已经与Java融为浑然一体,大家可以随手拿来使用

如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例

关键代码:

  1. 实现克隆操作,在Java中继承Cloneable,重写clone,在C语言中可以使用Object类的MemberWiseClone()方法来实现对象的浅拷贝或通过序列化的方式来实现深拷贝
  2. 原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,他同样要求这些“易变类”拥有稳定的接口

应用实例:

  1. 细胞分裂
  2. Java中的Object clone();方法

优点

  1. 性能提高
  2. 逃避构造函数的约束

缺点:

  1. 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定是容易的,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候
  2. 必须实现Cloneable接口

注意事项

  1. 与通过对一个类进行实例化来构造新对象不同的是原型模式是通过拷贝一个现有对象生成新对象的
  2. 浅拷贝实现Cloneable,重写
  3. 深拷贝是通过实现Serializable读取二进制流
  4. 有点赋值的意思

二、原型模式结构图

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

三、浅拷贝代码

逻辑代码

package com.proto;

/**
* 原型模式
* 1.Cloneable 替代了 MemberwiseClone()
* 2.就是浅拷贝了下,修改还是靠set
*
* @author 王子威
* @date 2022/7/28
*/
public class ConcretePrototypeOne implements Cloneable
{ private String name;
private String sex;
private String age;
private String timeArea;
private String company; /**
* 构造函数
* 初始化
* 加载简历人员
* @param name 名字
*/
public ConcretePrototypeOne(String name)
{
this.name = name;
} /**
* 个人信息
*
* @param sex 性别
* @param age 年龄
*/
public void setPersonalInfo(String sex, String age)
{
this.sex = sex;
this.age = age;
} /**
* 工作经历
*
* @param timeArea 时间
* @param company 公司
*/
public void setWorkExperience(String timeArea, String company)
{
this.timeArea = timeArea;
this.company = company;
} /**
* 显示内容
*/
public void Display()
{
System.out.println("name = " + name);
System.out.println("sex = " + sex);
System.out.println("age = " + age);
System.out.println("timeArea = " + timeArea);
System.out.println("company = " + company);
} /**
* 拷贝(原型模式关键点)
*
* @return 需要强转为自己需要的对象
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}

测试代码

package com.proto;

/**
* 原型模型测试方法
*
* @author 王子威
* @date 2022/7/28
*/
public class MainTest
{
public static void main(String[] args) throws CloneNotSupportedException
{
// 对象1
ConcretePrototypeOne a = new ConcretePrototypeOne("wzw");
a.setPersonalInfo("男","18");
a.setWorkExperience("1999-2000","xxx公司");
System.out.println("a = " + a); // 对象2
ConcretePrototypeOne b = (ConcretePrototypeOne) a.clone();
b.setWorkExperience("1999-2001","ooo公司");
System.out.println("b = " + b); // 对象3
ConcretePrototypeOne c = (ConcretePrototypeOne) a.clone();
c.setPersonalInfo("男","18");
System.out.println("c = " + c);      // 显示
a.Display();
b.Display();
c.Display();
}
}

结果图

四、深拷贝代码

逻辑代码

package com.proto;

/**
* 原型模式
* 1.Cloneable 替代了 MemberwiseClone()
* 2.这里采用的是深复制的方案进行处理过
* 3.将工作经历提取出来成为对象类
*
* @author 王子威
* @date 2022/7/28
*/
public class ConcretePrototypeTwo implements Cloneable
{ private String name;
private String sex;
private String age;
/**
* 引用工作经历对象
*/
private WorkExperience work; /**
* 构造函数
* 初始化
* 加载简历人员
*
* @param name 名字
*/
public ConcretePrototypeTwo(String name)
{
this.name = name;
// 在实体化简历时一起实体化“工作经历”对象
work = new WorkExperience();
} /**
* 拷贝工作经历对象
*
* @param work
* @throws CloneNotSupportedException
*/
private ConcretePrototypeTwo(WorkExperience work) throws CloneNotSupportedException
{
this.work = (WorkExperience) work.clone();
} /**
* 个人信息
*
* @param sex 性别
* @param age 年龄
*/
public void setPersonalInfo(String sex, String age)
{
this.sex = sex;
this.age = age;
} /**
* 工作经历
*
* @param timeArea 时间
* @param company 公司
*/
public void setWorkExperience(String timeArea, String company)
{
work.setTimeArea(timeArea);
work.setCompany(company);
} /**
* 显示内容
*/
public void Display()
{
System.out.println("name = " + name);
System.out.println("sex = " + sex);
System.out.println("age = " + age);
System.out.println("timeArea = " + work.getTimeArea());
System.out.println("company = " + work.getCompany());
} /**
* 深拷贝(原型模式关键点)
*
* @return 需要强转为自己需要的对象
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException
{
ConcretePrototypeTwo deepClone = new ConcretePrototypeTwo(this.work);
deepClone.name = this.name;
deepClone.sex = this.sex;
deepClone.age = this.age;
return deepClone;
}
}

测试代码

package com.proto;

import org.junit.Test;

/**
* 原型模型测试方法
*
* @author 王子威
* @date 2022/7/28
*/
public class MainTest
{
@Test
public void protoDeepClone() throws CloneNotSupportedException
{
// 对象1
ConcretePrototypeTwo a = new ConcretePrototypeTwo("wzw");
a.setPersonalInfo("男","18");
a.setWorkExperience("1999-2000","xxx公司");
System.out.println("a = " + a); // 对象2
ConcretePrototypeTwo b = (ConcretePrototypeTwo) a.clone();
b.setWorkExperience("1999-2001","ooo公司");
System.out.println("b = " + b); // 对象3
ConcretePrototypeTwo c = (ConcretePrototypeTwo) a.clone();
c.setWorkExperience("1999-2002","yyy公司");
System.out.println("c = " + c); // 显示
a.Display();
b.Display();
c.Display();
} }

结果图

五、总结

  1. 在Cloneable中有方法Clone(),这样你就只需要实现这个接口就可以完成原型模式了
  2. 实现了解耦,当只想改某一个对象内容时就直接修改,而且不会影响到其他的了
  3. 减少了构造函数执行的时间
  4. 一般在初始化的信息不发生改变的情况下,克隆是最好的方法,既隐藏了对象创建的细节,有对性能是大大的提高
  5. 不用重新初始化对象,而是动态的获取对象运行时的状态
  6. 深拷贝时需要注意再赋值和子对象的处理
  7. java基础之“深复制和浅复制的区别”

设计模式之“原型模式(ProtoType)”的更多相关文章

  1. 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

    原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...

  2. 二十四种设计模式:原型模式(Prototype Pattern)

    原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象.示例有一个Message实体类,现在要克隆它. MessageModel usin ...

  3. [设计模式] 4 原型模式 prototype

    设计模式:可复用面向对象软件的基础>(DP)本文介绍原型模式和模板方法模式的实现.首先介绍原型模式,然后引出模板方法模式. DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...

  4. 设计模式 笔记 原型模式 prototype

    //---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图: ...

  5. python 设计模式之原型模式 Prototype Pattern

    #引入 例子1: 孙悟空拔下一嘬猴毛,轻轻一吹就会变出好多的孙悟空来. 例子2:寄个快递下面是一个邮寄快递的场景:“给我寄个快递.”顾客说.“寄往什么地方?寄给……?”你问.“和上次差不多一样,只是邮 ...

  6. 【UE4 设计模式】原型模式 Prototype Pattern

    概述 描述 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.如孙悟空猴毛分身.鸣人影之分身.剑光分化.无限剑制 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象, ...

  7. 【设计模式】—— 原型模式Prototype

    前言:[模式总览]——————————by xingoo 模式意图 由于有些时候,需要在运行时指定对象时哪个类的实例,此时用工厂模式就有些力不从心了.通过原型模式就可以通过拷贝函数clone一个原有的 ...

  8. 创建型设计模式之原型模式(Prototype)

    结构   意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或 ...

  9. 设计模式五: 原型模式(Prototype)

    简介 原型模式是属于创建型模式的一种,是通过拷贝原型对象来创建新的对象. 万能的Java超类Object提供了clone()方法来实现对象的拷贝. 可以在以下场景中使用原型模式: 构造函数创建对象成本 ...

  10. 设计模式之原型模式(prototype)

    原理:拷贝自身对象实际上就是调用的拷贝构造函数,注意事项是这里的拷贝是深拷贝,即需要拷贝指针所指的内容 #include <stdio.h> #include <memory> ...

随机推荐

  1. vue+elementUI当渲染文本超出一定字数时显示省略号

    如图,当渲染的文字超出30字后显示省略号 1.设置过滤器 filters: { ellipsis(value) { if (!value) return ""; if (value ...

  2. QT5笔记: 20. QStringListModel的使用

    主要为 :添加.插入.修改.删除.清空等操作 例子:本例子中QListView 没有做任何处理,只是拖放至ui文件,设置了布局 MainWindow.h #ifndef MAINWINDOW_H #d ...

  3. Flink - [04] 窗口(Windows)

    题记部分 一.Flink中的窗口是什么 (1)一般真实的流都是无界的,怎样处理无界的数据? (2)可以把无限的数据流进行切分,得到有限的数据集进行处理 -- 也就是得到有界流 (3)窗口(Window ...

  4. K8s - 容器编排引擎Kubernetes

    什么是Kubernetes? 背景 Kubernetes 是开源的容器集群管理项目,诞生于2014年,由Google公司发起 前身Borg系统在Google内部应用了十几年,积累了大量来自生产环境的实 ...

  5. Scala样例类及底层实现伴生对象

    package com.wyh.day01 /** * 样例类的使用 * 1.使用case修饰类 * 2.不需要写构造方法,getter,setter方法,toString方法 * 3.直接通过对象名 ...

  6. 2024CSP-S邮寄

    前言 去年被沉重打击到了,不过从此以后心态就好很多了,不会因为什么考试动不动就崩溃了. 考前 一直在认真复习,也停了课,甚至差点错过运动会.从国庆开始听了几天课,消化课件,然后考试.考试的稳定性不高, ...

  7. js回忆录(3) -- 循环语句,前后缀运算符

    计算机对于大批量数据的处理速度比起人类不知道快了多少,因此对于重复的操作,使用循环语句处理是很方便的,对于我们前端来说,给同一标签的元素绑定事件啦,tab切换啦,左右联动效果啦,等等都可以使用循环语句 ...

  8. 抓包分析:wireshark抓不到TLS1.3数据包中证书的解决方案

    近日工作中遇到需要分析使用TLS1.3协议进行通信的数据包的情况,但使用wireshark进行分析发现不能抓到服务端证书,感到诧异遂设法解决 这篇博客给出解决方案,和简单的原理分析 解决方案: 第一步 ...

  9. 如何学习 ROS+PX4

    博客地址:https://www.cnblogs.com/zylyehuo/ 参考 https://www.bilibili.com/video/BV1vx4y1Y7Tu?spm_id_from=33 ...

  10. CDH6.3.2下安装部署Qualitis数据质量分析的计算服务Linkis1.3.2

    快速搭建Qualitis手册 一.基础软件安装 Gradle (4.6) MySQL (5.5+) JDK (1.8.0_141) Linkis(1.0.0+), 必装Spark引擎.如何安装Link ...