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学习笔记——设计模式之六.原型模式(浅克隆和深克隆)的更多相关文章

  1. Java学习笔记——设计模式之四.代理模式

    To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: p ...

  2. Java学习笔记——设计模式之八.外观模式

    外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 子系统: package cn.happy.design_patter ...

  3. Java学习笔记——设计模式之七.模板方法模式

    模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图: 代码: 算法骨架 ...

  4. C#设计模式之六原型模式(Prototype)【创建型】

    一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...

  5. C#设计模式学习笔记:(5)原型模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用.  一.引言 很多人说原型设计模式会节省机器内存,他们说 ...

  6. Java学习笔记——设计模式之二.策略模式

    明确是王道 --Clean Code 先定义策略类 package cn.no2.strategy; public abstract class Strategy { //省略属性 //算法方法 pu ...

  7. Java学习笔记——设计模式之九.建造者模式

     建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Product类: package cn.happy.design_pattern._09b ...

  8. Java进阶篇设计模式之六 ----- 组合模式和过滤器模式

    前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...

  9. Java学习笔记——设计模式之五.工厂方法

    水边一只青蛙在笑 --石头和水 工厂方法模式(Factory Method),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 这里在简单和工厂的基础上 ...

随机推荐

  1. Qt5.4.1在windows7配置Android开发环境(阳光柠檬_)

    网上的说法有些时间比较久远,软件更新又快,配置路上总有一些坎坷. 自己亲自尝试了一遍,记录下来. 所需的软件: 1. qt-opensource-windows-x86-android-5.4.1.e ...

  2. Matlab Tricks(二十六)—— 置乱(随机化)与恢复(shuffle/permutation & restore)

    x = 1:10; n = length(x); perm = randperm(n); x_perm = x(perm); % x_perm 表示置乱后的结果 x_ori(perm) = x_per ...

  3. ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 用户注册 上一章节我们终于迁移完了 Identity 的数据,也创建 ...

  4. 大约PCA算法学习总结

    文章来源:http://blog.csdn.net/xizhibei ============================= PCA,也就是说,PrincipalComponents Analys ...

  5. [Windows][VC]开机自动启动程序的几种方法

    原文:[Windows][VC]开机自动启动程序的几种方法 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能够启动运行,方法是写注册表Software\\Microsof ...

  6. github中README.md文件写法解析,git指令速查表

    http://blog.csdn.net/u012234115/article/details/41778701 http://blog.csdn.net/u012234115/article/det ...

  7. vagrant up 无法加载映像目录

    错误代码显示: ==> default: Attempting graceful shutdown of VM... ==> default: Clearing any previousl ...

  8. delphi 判断目录是否可写

    FUNCTION WritableDir(CONST Dir : STRING) : BOOLEAN; VAR FIL : FILE; N : STRING; I : Cardinal; BEGIN ...

  9. C#数字图像处理算法详解大全

    原文:C#数字图像处理算法详解大全 C#数字图像处理算法详解大全 网址http://dongtingyueh.blog.163.com/blog/#m=0 分享一个专业的图像处理网站(微像素),里面有 ...

  10. Linux下获取arm的交叉编译工具链

    转载请注明文章:Linux下获取arm的交叉编译工具链 出处:多客博图 这里介绍,Linux下获取arm的交叉编译工具链,比如arm-linux-gnueabihf-gcc.arm-linux-gne ...