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),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 这里在简单和工厂的基础上 ...
随机推荐
- 怎样从一名程序员过度到项目经理(整理自csdn论坛) 选择自 whoopee 的 Blog
1.从程序员到PM,是一条脱变的路,事实上程序员走的路最终不应该是项目经理.首先有一点需要明白的就是,一定规模的项目中,项目经理不需要太懂技术,他可以是一知半解.项目经理的任务不是在技术方面,技术相关 ...
- Entity framework 配置文件,实现类,测试类
配置文件信息App.config: 数据库IP地址为192.168.2.186 ,数据库名为 Eleven-Six , 用户名 123456,密码654321 <?xml version=&qu ...
- JS注册事件
<html xmlns="http://www.w3.org/1999/xhtml"><head> <title></title&g ...
- WPF数据验证方式
WPF有两种数据验证的方式: 1 在数据对象上进行验证:普通属性验证或者实现IDataErrorInfo接口 2 可以再绑定规则上进行验证:ExceptionValidationRule异常验证规则 ...
- WPF中任意Object的XAML代码格式化输出
原文:WPF中任意Object的XAML代码格式化输出 有时候,我们需要将WPF中的控件自身的XAML代码输出成文本,那么,我们可以使用System.Windows.Markup.XamlWriter ...
- iOS UITableView动态隐藏或显示Item
通过改变要隐藏的item的高度实现隐藏和显示item 1.创建UITableView #import "ViewController.h" @interface ViewContr ...
- qt下的时钟程序(简单美丽,继承自QWidget的Clock,用timer调用update刷新,然后使用paintEvent作画就行了,超详细中文注释)good
最近抽空又看了下qt,发现用它来实现一些东西真的很容易比如下面这个例子,绘制了个圆形的时钟,但代码却清晰易懂[例子源自奇趣科技提供的例子]因为清晰,所以就只写注释了,吼吼其实也就这么几行代码头文件 / ...
- Centos重启关机命令
Linux centos重启命令: 1.reboot 普通重启 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 10 过10分钟自动重启(root用户 ...
- WPF 用Main函数方式启动程序
原文:WPF 用Main函数方式启动程序 WPF默认程序启动:新建project后自动生成的App.xaml中指定程序启动方式(StartupUri="MainWindow.xaml&quo ...
- PHPstudy + phpstrom +xdebug 断点调试(windows) - CSDN博客
原文:PHPstudy + phpstrom +xdebug 断点调试(windows) - CSDN博客 php.ini 配置 需要添加如下内容 [XDebug]xdebug.profiler_ou ...