一、原型模式(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. Git钩子-每次提交信息添加分支名称

    Git钩子是一组脚本,这些脚本对应着Git仓库中的特定事件,每一次事件发生时,钩子会被触发.这允许你可以定制化Git的内部行为,在开发周期中的关键点上触发执行定制化的脚本. 钩子脚本文件通常放置于项目 ...

  2. FANUCR2000iB发那科机器人保养有哪些

      1.机器人保养的重要性   机器人都需要预防性保养,这样可以保证它们在生产线上保持最佳性能和实现一致性.当机器人没有进行定期的预防性保养检查,可能会导致零部件损坏或故障,从而致使生产放慢甚至停机. ...

  3. linux报错-bash: ./xx.sh: Permission denied

    linux报错-bash: ./xx.sh: Permission denied 在linux下执行sh文件时提示:-bash: ./xx.sh: Permission denied 进行授权:chm ...

  4. 移动硬盘插入win10检测到却不显示盘符解决方法

    1.开始菜单中的设置-----设备. 2.选择"蓝牙和其他设备" 3.在其他设备栏中就能看到检测到的移动硬盘,点击删除设备后重新插入移动硬盘即可在此电脑上显示盘符.

  5. 用于敏捷开发的最佳免费 UML 工具 2022

    Table of Contents  hide  1 最好的在线免费 UML图工具 2 免费的 UML Visual Paradigm 在线平台 3 其他福利 4 用于正式和大规模可视化建模的 Vis ...

  6. Java、Python等接入方式对接股票数据源API接口

    为了创建一个Python项目来对接StockTV的API接口,我们可以使用requests库来发送HTTP请求,并使用websocket-client库来处理WebSocket连接.以下是一个简单的P ...

  7. 用状态模式开发一个基于WPF的截图功能

    状态模式 状态模式是设计模式中的一种行为设计模式,对很多人来说,这个模式平时可能用不到.但是如果你做游戏开发的话,我相信你应该对这个模式有一个很深刻的理解.状态模式在游戏中开发中还是比较常见的.状态模 ...

  8. ORACLE数据挖掘之 MSET-SPRT

    虽然是熟悉的Oracle数据库,但关于机器学习.数据挖掘这方面的知识笔者起初也是不了解的,文中MSET相关设置来源于同事提供的sample,在测试过程中边查资料边学习吸收,也因此看到了别样的Oracl ...

  9. 双剑合璧:kubectx+kubens玩转Kubernetes多集群管理

    在同时管理多个Kubernetes集群和数十个命名空间时,频繁输入--context和--namespace参数堪称效率杀手.由Ahmetb开发的kubectx/kubens工具组,用极简命令实现集群 ...

  10. K8S组件详解

    K8S的控制平面.和工作节点是集群正常运行的核心,通过这两部分的协同工作,K8S才能够实现高效的容器编排.管理.和自动化运维. K8S Kubernetes(简称K8s),是一个开源的容器编排平台,用 ...