一、原型模式简介

1、基础概念

原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。

2、模式结构

原型模式要求对象实现一个可以“克隆”自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。

3、代码实现

1)、UML关系图

Java描述设计模式(05):原型模式
2)、核心角色

这种形式涉及到三个角色:

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

2)、抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

3)、具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。

3)、基于JDK源码实现

/*** 基于JDK源码方式实现原型模式*/
public class C01_Property {public static void main(String[] args) {Product product = new Product("机械键盘","白色",100.00) ;Product product1 = (Product) product.clone();Product product2 = (Product) product.clone();System.out.println(product1);System.out.println(product2);System.out.println(product1==product2);  // false}
}
class Product implements Cloneable {private String name ;private String color ;private Double price ;public Product(String name, String color, Double price) {this.name = name;this.color = color;this.price = price;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", color='" + color + '\'' +", price=" + price +'}';}@Overrideprotected Object clone() {Product product = null ;try{product = (Product)super.clone() ;} catch (Exception e){e.printStackTrace();}return product ;}// 省略GET和SET方法
}

二、Spring框架应用

1、配置文件

<!-- 多例Bean -->
<bean id="sheep01" class="com.model.design.spring.node05.property.Sheep" scope="prototype" />
<!-- 单例Bean 默认: scope="singleton" -->
<bean id="sheep02" class="com.model.design.spring.node05.property.Sheep"/>

2、测试代码块

@Test
public void test01 (){ApplicationContext context01 = new ClassPathXmlApplicationContext("/spring/spring-property.xml");// 原型模式Sheep sheep1 = (Sheep)context01.getBean("sheep01") ;Sheep sheep2 = (Sheep)context01.getBean("sheep01") ;System.out.println(sheep1==sheep2); // false// 单例模式Sheep sheep3 = (Sheep)context01.getBean("sheep02") ;Sheep sheep4 = (Sheep)context01.getBean("sheep02") ;System.out.println(sheep3==sheep4); // true
}

3、核心源码

  • 所在类:org.springframework.beans.factory.support.AbstractBeanFactory
  • 所在方法:doGetBean

1)、执行流程

if (mbd.isSingleton()) {sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {try {return AbstractBeanFactory.this.createBean(beanName, mbd, args);} catch (BeansException var2) {AbstractBeanFactory.this.destroySingleton(beanName);throw var2;}}});bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {var11 = null;Object prototypeInstance;try {this.beforePrototypeCreation(beanName);prototypeInstance = this.createBean(beanName, mbd, args);} finally {this.afterPrototypeCreation(beanName);}bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

2)、单例多例判断

所以默认就是单例模式,指定[scope=“prototype”]就是原型模式。

public boolean isSingleton() {return "singleton".equals(this.scope) || "".equals(this.scope);
}
public boolean isPrototype() {return "prototype".equals(this.scope);
}

三、深浅拷贝

1、浅拷贝

  1. 数据类型是基本数据类型、String类型的成员变量,浅拷贝直接进行值传递,也就是将该属性值复制一份给新的对象。
  2. 数据类型是引用数据类型的成员变量,比如说成员变量是数组、类的对象等,浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。实际上两个对象的成员变量都指向同一个实例。修改其中一个对象属性会影响到另一个对象的属性。
  3. 浅拷贝是使用默认的 clone()方法来实现。

2、深拷贝

1)、概念描述

除了浅拷贝要拷贝的值外,还负责拷贝引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象,这种对被引用到的对象的复制叫做间接复制。

2)、源代码实现

序列化实现深度克隆

对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。

在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。

/*** 深拷贝和浅拷贝对比案例*/
public class C02_DeepClone {public static void main(String[] args) throws Exception {Dog dog = new Dog("Tom") ;Dog dog1 = (Dog)dog.clone() ;Dog dog2 = (Dog)dog.clone() ;// dog1:1639622804;dog2:1639622804System.out.println("dog1:"+dog1.cat.hashCode()+";dog2:"+dog2.cat.hashCode());Dog dog3 = (Dog)dog.deepClone() ;Dog dog4 = (Dog)dog.deepClone() ;// dog3:1937348256;dog4:1641808846System.out.println("dog3:"+dog3.cat.hashCode()+";dog4:"+dog4.cat.hashCode());}
}class Cat implements Serializable {public String name ;public Cat (String name){this.name = name ;}
}
class Dog implements Cloneable,Serializable {public String name ;public Cat cat ;public Dog (String name){this.name = name ;this.cat = new Cat("Kit") ;}@Overrideprotected Object clone() {Dog dog = null ;try{dog = (Dog)super.clone() ;} catch (Exception e){e.printStackTrace();}return dog ;}public Object deepClone() throws IOException, ClassNotFoundException{//将对象写到流里面:序列化ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//从流里面读出对象:反序列化ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return ois.readObject();}
}

四、优缺点总结

1、优点总结

原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间,由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。

2、缺点总结

原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候。

五、源代码地址

GitHub地址:知了一笑
https://github.com/cicadasmile/model-arithmetic-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/model-arithmetic-parent


Java描述设计模式(05):原型模式相关推荐

  1. 初学Java常用设计模式之——原型模式

    声明:转载请附上原文链接 提示:标题序号从3开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--工厂模式 序号从2开始. 标题后面之所以加上了解,是因为相对 ...

  2. java prototype是什么,java设计模式-原型模式(Prototype)

    定义 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象.这就是原型模式的用意 原型模式的结构 原型模式要求对象实现同一个可 ...

  3. 【Java设计模式】原型模式

    ✍ 在软件系统中 , 有些对象的创建过程较为复杂 , 而且有时候需要频繁创建 , 原型模式通过给出一个原型对象来指明所要创建的对象的类型 , 然后用复制这个原型对象的办法创建出更多同类型的对象, 这就 ...

  4. 23天读懂23种设计模式:原型模式(创建型)

    点击上方 蓝字 关注我们 创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建.组合和表示方式. 原型模式目的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...

  5. 【GOF23设计模式】原型模式

    [GOF23设计模式]原型模式 来源:http://www.bjsxt.com/  一.[GOF23设计模式]_原型模式.prototype.浅复制.深复制.Cloneable接口  浅复制 1 pa ...

  6. 设计模式回顾——原型模式(C++)

    文章目录 1 前言 2 什么是原型模式 2.1 原型模式组成 2.2 原型模式UML图 2.3 原型模式作用 3 原型模式优缺点 4 什么地方使用原型模式 5 原型模式实现 6 原型模式与构造函数 1 ...

  7. 设计模式之 原型模式

    原型模式应用场景举例:  GG和MM经常在QQ上聊天,但是GG打字的速度慢如蜗牛爬行,每次MM在瞬间完成恢复或者问候是,GG都会很紧张的去尽力快速打字,尽管如此,还是让MM有些不高心,MM说回复信息这 ...

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

    [索引页] [源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. ...

  9. 教你如何一篇博客读懂设计模式之—--原型模式

    教你如何一篇博客读懂设计模式之----原型模式 what:是什么 原型模式: 用于创建重复的对象,既不用一个属性一个属性去set和get,又不影响性能,原型模式产生的对象和原有的对象不是同一个实例,他 ...

最新文章

  1. virtualbox虚拟机XP连接本地WinXP
  2. [No000092]SVN学习笔记3-Import/Checkout(迁入/迁出),GetLock(加锁)
  3. [android] 切换按钮-自定义控件-拖动效果
  4. Spring Boot2.x-04Spring Boot基础-使用注解装配bean
  5. PAT甲级题目翻译+答案 AcWing(哈希表)
  6. 基于倒谱法、自相关法、短时幅度差法的基音频率估计算法(MATLAB及验证)
  7. SSH ALL-IN-ONE
  8. Robot Framework连接MySQL数据库
  9. js结束当前循环关键词_干货||什么是事件循环机制
  10. 手机浏览器都是按照什么分辨率解析移动端网页的
  11. Hibernate官网下载最新版jar包
  12. Java 转换EXCEL Duble格式时间为指定格式日期字符串
  13. Invocation failed Unexpected end of file from server
  14. mysql5.7优化
  15. 抖音 iOS 工程架构演进
  16. 机械祭天法力无边:练习3.5:编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。
  17. springboot+英语在线学习系统 毕业设计-附源码211714
  18. hp linux 禁用u盘启动,BIOS关闭Secure Boot(安全启动)方法大全(联想,华硕,DELL,HP等品牌)...
  19. 异常检测(Anomaly detection)方法小结
  20. MSP430平台下实现Si4432的收发数据

热门文章

  1. 九度OJ : 1004 Median
  2. 100万并发连接服务器笔记之测试端就绪
  3. 1203. 项目管理
  4. 从零开始学PowerShell(1)初见基础命令
  5. kvm虚拟机网络设置隔离模式(一键shell脚本)
  6. Windows平台下Go语言的安装和环境变量设置
  7. 【ELK】之Kibana使用
  8. js判断软键盘是否开启弹出
  9. vs2013 git 使用总结
  10. meta http-equiv=X-UA-Compatible content=IE=edge / 的说明