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),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 这里在简单和工厂的基础上 ...
 
随机推荐
- 大数据_zookeeper环境搭建中的几个坑
			
文章目录 [] Zookeeper简介 关于zk的介绍, zk的paxos算法, 网上已经有各位大神在写了, 本文主要写我在搭建过程中的几个极有可能遇到的坑. Zookeeper部署中的坑 坑之一 E ...
 - Android Camera2拍照(一)——使用SurfaceView
			
原文:Android Camera2拍照(一)--使用SurfaceView Camera2 API简介 Android 从5.0(21)开始,引入了新的Camera API Camera2,原来的a ...
 - SQL SERVER LEAD和LAG使用
			
示例:获取在48小时之内重复的记录 SELECT * FROM ( SELECT b.* , LAG(b.OperatorTime, , b.OperatorTime) OVER ( PARTITIO ...
 - 【C#】wpf自定义calendar日期选择控件的样式
			
原文:[C#]wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 ...
 - WPF分辨率适应
			
double x = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度 double y = SystemParameters.WorkArea.Height; ...
 - TLD单目标跟踪算法程序详解--OpenTLD Code 详解
			
TLD算法原理介绍:http://www.cnblogs.com/liuyihai/p/8306419.html OpenTLD源代码页: https://github.com/zk00006/Ope ...
 - Win10《芒果TV》内测版现已支持在国行版 Xbox One 下载体验
			
Win10<芒果TV>内测版现已支持在国行版 Xbox One 下载体验 关于国行为什么无法从商店下载安装芒果TV内测版(来自微软) 1.截至到目前<芒果TV - Preview&g ...
 - 把#define宏转换成指定格式
			
之前在弄一个东西的,有一大堆的宏,需要把它转换成其它的形式.遇到这种大批量的东西,我特别没有耐心去一个一个的弄,于是写了一段代码. 估计大家平常比较难用得上,不过可以平常相似的情况用来参考. Sort ...
 - 龙芯GO!龙芯平台上构建Go语言环境指南
			
龙芯软件生态系列——龙芯GO!龙芯平台上构建Go语言环境指南2016-07-05 龙芯中科1初识Go语言Go语言是Google公司于2009年正式推出的一款开源的编程语言,是由Robert Gries ...
 - [机器学习]Generalized Linear Model
			
最近一直在回顾linear regression model和logistic regression model,但对其中的一些问题都很疑惑不解,知道我看到广义线性模型即Generalized Lin ...