Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)
That there's some good in this world, Mr. Frodo. And it's worth fighting for.

原型模式(prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
至于Object.clone()这里就不赘述了。文档看起来可能有些难懂,直接上代码反而更容易理解:
浅克隆:
package cn.happy.design_pattern._06prototype.shallowclone;
public abstract class Prototype {
private String id;
String getId() {
return id;
}
void setId(String id) {
this.id = id;
}
public abstract Prototype mClone();
}
package cn.happy.design_pattern._06prototype.shallowclone;
public class ConcretePrototype extends Prototype implements Cloneable{
private Obj obj;
public ConcretePrototype() {
super();
obj = new Obj();
}
/*
* getter and setter
*/
Obj getObj() {
return obj;
}
void setObj(Obj obj) {
this.obj = obj;
}
@Override
public Prototype mClone() {
// TODO Auto-generated method stub
Prototype prototype = null;
try {
prototype = (Prototype)this.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return prototype;
}
}
package cn.happy.design_pattern._06prototype.shallowclone;
public class Obj {
private String name;
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
}
package cn.happy.design_pattern._06prototype.shallowclone;
public class Mmain {
public static void main(String[] args) {
ConcretePrototype c1 = new ConcretePrototype();
ConcretePrototype c2 = (ConcretePrototype)c1.mClone();
c1.setId("原型");
c1.getObj().setName("张三");
c2.setId("副本");
c2.getObj().setName("李四");
/*
* 浅克隆:
* Id是值类型变量,逐位复制,产生新的变量地址;Obj是引用变量,只复制引用,副本和原型共享同一变量地址;
* 输出:prototype.shallowclone.ConcretePrototype@15db9742,原型,李四
* prototype.shallowclone.ConcretePrototype@6d06d69c,副本,李四
*/
System.out.println(c1+","+c1.getId()+","+c1.getObj().getName());
System.out.println(c2+","+c2.getId()+","+c2.getObj().getName());
}
}
这里需要提下两种特殊的值类型变量,字符串(其实字符串底层是char数组)和数组。它们虽然是引用类型但是可被浅克隆。大家一试便知。
深克隆:
Prototype 类不变。
package cn.happy.design_pattern._06prototype.deepclone;
public class ConcretePrototype extends Prototype implements Cloneable{
private Obj obj;
public ConcretePrototype() {
super();
obj = new Obj();
}
//添加新的构造方法
private ConcretePrototype(Obj obj) {
super();
this.obj = (Obj) obj.mClone();
}
/*
* getter and setter
*/
Obj getObj() {
return obj;
}
void setObj(Obj obj) {
this.obj = obj;
}
@Override
public Prototype mClone() {
// TODO Auto-generated method stub
Prototype prototype = null;
//调用新的构造方法
prototype = new ConcretePrototype(getObj());
prototype.setId(getId());
return prototype;
}
}
package cn.happy.design_pattern._06prototype.deepclone;
public class Obj implements Cloneable{
//省略属性,这里也许需要更深层克隆。
public Object mClone(){
Obj obj = null;
try {
obj = (Obj)this.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
测试类:
package cn.happy.design_pattern._06prototype.deepclone;
public class Mmain {
public static void main(String[] args) {
ConcretePrototype c1 = new ConcretePrototype();
ConcretePrototype c2 = (ConcretePrototype)c1.mClone();
/*
* 深克隆:c1与c2中Obj的地址不同了
* 输出:...ConcretePrototype@15db9742,null,...Obj@6d06d69c
* ...ConcretePrototype@7852e922,null,...Obj@4e25154f
*/
System.out.println(c1+","+c1.getId()+","+c1.getObj());
System.out.println(c2+","+c2.getId()+","+c2.getObj());
}
}
Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)的更多相关文章
- Java学习笔记——设计模式之四.代理模式
To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: p ...
- Java学习笔记——设计模式之八.外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 子系统: package cn.happy.design_patter ...
- Java学习笔记——设计模式之七.模板方法模式
模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图: 代码: 算法骨架 ...
- C#设计模式之六原型模式(Prototype)【创建型】
一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...
- C#设计模式学习笔记:(5)原型模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用. 一.引言 很多人说原型设计模式会节省机器内存,他们说 ...
- Java学习笔记——设计模式之二.策略模式
明确是王道 --Clean Code 先定义策略类 package cn.no2.strategy; public abstract class Strategy { //省略属性 //算法方法 pu ...
- Java学习笔记——设计模式之九.建造者模式
建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Product类: package cn.happy.design_pattern._09b ...
- Java进阶篇设计模式之六 ----- 组合模式和过滤器模式
前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...
- Java学习笔记——设计模式之五.工厂方法
水边一只青蛙在笑 --石头和水 工厂方法模式(Factory Method),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 这里在简单和工厂的基础上 ...
随机推荐
- 1.跟着微软 https://docs.microsoft.com/zh-cn/dotnet/core/ 学习.net core
10分钟快速使用 安装之后 打开cmd 第一步. dotnet new console -o firstApp 第二步. cd firstApp 第三部.dotnet run 这样就运行了hello ...
- MyEclipse使用汇总——MyEclipse10设备SVN插入
一.下载SVN插件subclipse 下载地址:folderID=2240" style="color:rgb(7,93,179)">http://subclips ...
- c#调api串口通讯
原文:c#调api串口通讯 在调试ICU通信设备的时候,由于串口通信老出现故障,所以就怀疑CF实现的SerialPort类是否有问题,所以最后决定用纯API函数实现串口读写. 先从网上搜索相关代码(关 ...
- x:Static , StaticResource 和DynamicResource等XAML 扩展用法
原文:x:Static , StaticResource 和DynamicResource等XAML 扩展用法 前提: <system:String x:Key="{Component ...
- Entity framework 更改模型,新增表
在Package Manager Console 中运行命令Enable-Migrations 再次运行可以更新 抄袭 在实体类中增加一个属性以后,执行 Update-Database 命令 ,可以更 ...
- 微信红包功能(含示例demo)
开通支付权限 登录微信公众平台管理后台,找到“微信支付”一栏,进行开通会跳转到“微信支付商户平台”,根据提示提交相关证明,完成支付权限的开通开通之后,“微信支付”一栏会显示相关信息,在“开发-接口权限 ...
- Prism框架在项目中使用
本文大纲 1.Prism框架下载和说明 2.Prism项目预览及简单介绍. 3.Prism框架如何在项目中使用. Prism框架下载和说明 Prism框架是针对WPF和Silverlight的MVVM ...
- 2018年Unity结合Android SDK下载安装及配置教程
原文:2018年Unity结合Android SDK下载安装及配置教程 首先声明: Unity版本2017.1f3 最近试着在Unity中利用网易做AR开发时,发布项目文件需要发布到An ...
- XAML的命名空间
原文:XAML的命名空间 一个最简单的XAML例子 <Window x:Class="WpfApplication1.MainWindow" xmlns="ht ...
- 赵伟国:陆资无法进入台湾紫光要到WTO控告(芯片是为了经济安全,高通找的人不是很聪明)
集微网消息,昨天由全球半导体联盟和上海市集成电路行业协会联合举办的Memory +论坛在上海举行,会议透过来自存储器.逻辑和系统市场领先企业的高管,深入他们对未来存储器的应用.可行的商业模式,以及逻辑 ...