03 原型模式(prototype)
03 原型模式(prototype)
1 克隆羊问题
现在有一只羊tom,姓名为: tom。年龄为: 1,颜色为:白色,请编写程序创建和tom羊属性完全相同的10只羊。
2 传统方式解决
思路
classDiagram
Client ..> Sheep : 依赖
class Client{}
class Sheep{
name String
age int
}new十只羊出来。
3 传统方式优缺点
- 优点是比较好理解,简单易操作。
- 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低总是需要重新初始化对象,而不是动态地获得对象运行时的状态。不够灵活
4 改进的思路分析
- Java中 Object类是所有类的根类,Object类提供了一个clone()方法,该方法可以将一个Java对象复制一份,但是需要实现clone的Java类必须要实现一个接口
Cloneable,该接口表示该类能够复制且具有复制的能力→原型模式
5 原型模式
原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节
工作原理是:通过将一个原型对象传给要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即
object.clone()原理结构图类图
classDiagram
ConcretePrototype1 ..|> Prototype
ConcretePrototype2 ..|> Prototype
Client ..> Prototype
class Client{}
class Prototype{
+Clone()
}
class ConcretePrototype1{
+Clone()
}
class ConcretePrototype2{
+Clone()
}原理结构图说明
Prototype:原型类,声明一个克隆自己的接口ConcretePrototype:具体的原型类,实现一个克隆自己的操作Client:让一个原型对象克隆自己,从而创建一个新的对象(属性一样)
6 浅拷贝
对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。
对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。
因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。
浅拷贝是使用默认的clone()方法来实现的。
sheep = (Sheep)super.clone();
7 深拷贝
复制对象的所有基本数据类型的成员变量值
为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象进行拷贝。
深拷贝实现方式
- 重写clone方法来实现深拷贝。
- 通过对象序列化实现深拷贝(推荐)
//DeepPrototyped的引用类型
class DeepCloneTarget implements Serializable, Cloneable
{
private static final long serialVersionUID = 1L;
private String cloneName;
private String cloneClass;
//构造器
public DeepCloneableTarget(String cloneName, String cloneClass){
this.cloncName = cloncName;
this.cloneClass = cloneClass;
}
//因为该类的属性,都是String,因此我们这里使用默认的clone完成即可
@Override
protected Object clonc() throws CloncNotSupportedException {
return super.clone();
}
) class DeepPrototype{
public String name; // String属性
public DeepCloneableTarget deepCloneableTarget;// 引用类型
public DeepProtoType( {
super();
} //深拷贝-方式1使用clone方法
@override
protected 0bject clone() throws cloneNotSupportedException {
object deep = null;
//这里完成对基本数据类型(属性)和String的克隆deep = super.clone();
DeepProtoType deepProtoType = (DeepProtoType)deep;
//对引用类型的属性,进行单独处理
deepProtoType.deepcloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();
return deepProtoType;
} //深拷贝-方式2通过对象的序列化实现(推荐)
public 0bject deepClone() {
//创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputstream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeobject(this); //当前这个对象以对象流的方式输出 //反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
DeepPrototype copyObject = (DeepPrototype)ois.readObject();
return copyObject;
} catch(Exception e){
e.printStackTrace();
return null;
} finally{
try{
bos.close();
oos.close();
bis.close();
ois.close();
} catch(Exception e2){
e.printStackTrace();
}
}
}
8 原型模式在Spring框架中应用
原型Bean的创建,就是原型模式的应用
9 注意事项
- 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率
- 不用重新初始化对象,而是动态地获得对象运行时的状态
- 如果原始对象发生变化(增加或者减少属性),其它克隆对象的也会发生相应的变化,无需修改代
- 在实现深克隆的时候可能需要比较复杂的代码
- 缺点:需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源代码,违背了
ocp原则。
03 原型模式(prototype)的更多相关文章
- Net设计模式实例之原型模式( Prototype Pattern)
一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...
- 二十四种设计模式:原型模式(Prototype Pattern)
原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象.示例有一个Message实体类,现在要克隆它. MessageModel usin ...
- 设计模式(四)原型模式Prototype(创建型)
设计模式(四)原型模式Prototype(创建型) 1. 概述 我们都知道,创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些对象的操作,我们通过原型模式可以快速的创建一个对象 ...
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...
- 原型模式-Prototype(Java实现)
原型模式-Prototype 通过复制(克隆.拷贝)一个指定类型的对象来创建更多同类型的对象. 就像去蛋糕店买蛋糕一样. 柜台里的蛋糕都是非卖品. 只是为顾客提供一种参照. 当顾客看上某一个样式的蛋糕 ...
- 原型模式 prototype 创建型 设计模式(七)
原型模式 prototype 意图 用原型实例指定需要创建的对象的类型,然后使用复制这个原型对象的方法创建出更多同类型的对象 显然,原型模式就是给出一个对象,然后克隆一个或者更多个对象 小时候看 ...
- PHP设计模式 原型模式(Prototype)
定义 和工厂模式类似,用来创建对象.但实现机制不同,原型模式是先创建一个对象,采用clone的方式进行新对象的创建. 场景 大对象的创建. 优点 1.可以在运行时刻增加和删除产品 2.可以改变值或结构 ...
- 设计模式系列之原型模式(Prototype Pattern)——对象的克隆
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 六个创建模式之原型模式(Prototype Pattern)
定义: 使用原型实例指定创建对象的种类,并通过拷贝这个原型的属性创建新的对象. 结构图: Prototype:抽象原型类,声明克隆方法的接口,并是所有原型类的公共父类.在Java中,Object类为该 ...
随机推荐
- Jmeter设计压力测试场景
1.哪些业务需要做压力测试? 比较常用的功能模块 单一业务场景或者多业务场景 项目需要做的业务场景 2.压力测试的并发数是多少? 有预期的数值?一次性达到?有上次性能测试的结果值? 无预期的数值?只有 ...
- ps 树形显示
ps -axjf|grep swoft
- RedisManager2020.4最最最最简单的破解方式
前言 redis manager是一款很优秀的redis数据库可视化工具,果然优秀的软件最终都走向了收费,贫民玩家越来越难了.赶时间的直接拉到最后,有下载方式. 破解 无需破解,已是破解版 安装 下载 ...
- docker启动redis并设置密码
docker启动redis并设置密码: docker run -d --name redis -p 6379:6379 redis --requirepass "password" ...
- ServletResponse使用介绍
ServletResponse为将响应发送到客户端的对象:Servlet 容器创建 ServletResponse 对象,并将它作为参数传递给Servlet的service 方法,如下图 : Http ...
- Qlik Sense插件及QRS接口补充
date: 2019-10-18 09:10:00 updated: 2019-10-18 15:18:00 Qlik Sense插件及QRS接口补充 1.插件 1.1 获取数据方式 理论上 Engi ...
- vue-cli3生产环境和开发环境路径的替换
在根目录下创建两个文件,这样的好处在于不用手动去书写判断环境替换路径代码 .env.development(开发) .env.production(生产) 内容: 必须是VUE_APP前缀开头,这样w ...
- Verification of WISHBONE I2C Master Core(IRUN+Simvision)
一.前言 很久没写技术博客了,有些懈怠,生活还得继续折腾.转眼工作一年多,时间越长越发觉得自己知之甚少,当然这跟IC行业技术密集有关.用空余时间在opencores网站上下载些小的IP看看 验证下,让 ...
- 关于appium
一.特点 1.appium是开源的移动端自动化测试框架: 2.appium可以测试原生的.混合的.以及移动端的web项目: "移动原生应用"是指那些用iOS或者 Android S ...
- 简单Emacs配置
(global-set-key [f9] 'compile-file) (global-set-key [f10] 'gud-gdb) (global-set-key (kbd "C-s&q ...