• Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)


     That there's some good in this world, Mr. Frodo. And it's worth fighting for.

     

    原型模式(prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    至于Object.clone()这里就不赘述了。文档看起来可能有些难懂,直接上代码反而更容易理解:

    浅克隆:

     1 package cn.happy.design_pattern._06prototype.shallowclone;
     2 
     3 public abstract class Prototype {
     4 
     5     private String id;
     6 
     7     String getId() {
     8         return id;
     9     }
    10 
    11     void setId(String id) {
    12         this.id = id;
    13     }
    14     
    15     public abstract Prototype mClone();
    16 }
     1 package cn.happy.design_pattern._06prototype.shallowclone;
     2 
     3 public class ConcretePrototype extends Prototype implements Cloneable{
     4 
     5     private Obj obj;
     6     public ConcretePrototype() {
     7         super();
     8         obj = new Obj();
     9     }
    10 
    11     /*
    12      * getter and setter
    13      */
    14     Obj getObj() {
    15         return obj;
    16     }
    17 
    18 
    19     void setObj(Obj obj) {
    20         this.obj = obj;
    21     }
    22 
    23 
    24     @Override
    25     public Prototype mClone() {
    26         // TODO Auto-generated method stub
    27         Prototype prototype = null;
    28         try {
    29             prototype = (Prototype)this.clone();
    30         } catch (CloneNotSupportedException e) {
    31             // TODO Auto-generated catch block
    32             e.printStackTrace();
    33         }
    34         return prototype; 
    35     }
    36 
    37 }
     1 package cn.happy.design_pattern._06prototype.shallowclone;
     2 
     3 public class Obj {
     4 
     5     private String name;
     6 
     7     String getName() {
     8         return name;
     9     }
    10 
    11     void setName(String name) {
    12         this.name = name;
    13     }
    14     
    15 }
     1 package cn.happy.design_pattern._06prototype.shallowclone;
     2 
     3 public class Mmain {
     4 
     5     public static void main(String[] args) {
     6         ConcretePrototype c1 = new ConcretePrototype();
     7         ConcretePrototype c2 = (ConcretePrototype)c1.mClone();
     8         c1.setId("原型");
     9         c1.getObj().setName("张三");
    10         c2.setId("副本");
    11         c2.getObj().setName("李四");
    12         /*
    13          *  浅克隆:
    14          *  Id是值类型变量,逐位复制,产生新的变量地址;Obj是引用变量,只复制引用,副本和原型共享同一变量地址;
    15          *  输出:prototype.shallowclone.ConcretePrototype@15db9742,原型,李四
    16          *       prototype.shallowclone.ConcretePrototype@6d06d69c,副本,李四
    17          */
    18         System.out.println(c1+","+c1.getId()+","+c1.getObj().getName());
    19         System.out.println(c2+","+c2.getId()+","+c2.getObj().getName());
    20 
    21     }
    22 
    23 }

    这里需要提下两种特殊的值类型变量,字符串(其实字符串底层是char数组)和数组。它们虽然是引用类型但是可被浅克隆。大家一试便知。

    深克隆:

    Prototype 类不变。

     1 package cn.happy.design_pattern._06prototype.deepclone;
     2 
     3 public class ConcretePrototype extends Prototype implements Cloneable{
     4 
     5     private Obj obj;
     6     public ConcretePrototype() {
     7         super();
     8         obj = new Obj();
     9     }
    10     //添加新的构造方法
    11     private ConcretePrototype(Obj obj) {
    12         super();
    13         this.obj = (Obj) obj.mClone();
    14     }
    15 
    16 
    17     /*
    18      * getter and setter
    19      */
    20     Obj getObj() {
    21         return obj;
    22     }
    23 
    24 
    25     void setObj(Obj obj) {
    26         this.obj = obj;
    27     }
    28 
    29 
    30     @Override
    31     public Prototype mClone() {
    32         // TODO Auto-generated method stub
    33         Prototype prototype = null;
    34         //调用新的构造方法
    35         prototype = new ConcretePrototype(getObj());
    36         prototype.setId(getId());
    37         return prototype; 
    38     }
    39 
    40 }
     1 package cn.happy.design_pattern._06prototype.deepclone;
     2 
     3 public class Obj implements Cloneable{
     4   //省略属性,这里也许需要更深层克隆。
     5     public Object mClone(){
     6         Obj obj = null;
     7         try {
     8             obj = (Obj)this.clone();
     9         } catch (CloneNotSupportedException e) {
    10             // TODO Auto-generated catch block
    11             e.printStackTrace();
    12         }
    13         return obj;
    14     }
    15 }

    测试类:

     1 package cn.happy.design_pattern._06prototype.deepclone;
     2 
     3 public class Mmain {
     4 
     5     public static void main(String[] args) {
     6         ConcretePrototype c1 = new ConcretePrototype();
     7         ConcretePrototype c2 = (ConcretePrototype)c1.mClone();
     8         /*
     9          *  深克隆:c1与c2中Obj的地址不同了
    10          *  输出:...ConcretePrototype@15db9742,null,...Obj@6d06d69c
    11          *       ...ConcretePrototype@7852e922,null,...Obj@4e25154f
    12          */
    13         System.out.println(c1+","+c1.getId()+","+c1.getObj());
    14         System.out.println(c2+","+c2.getId()+","+c2.getObj());
    15 
    16     }
    17 
    18 }
  • 相关阅读:
    纯js实现10分钟倒计时
    js中的constructor
    双指放大缩小问题(不需要第三方插件)
    js异步加载的3种方式(转载)
    5种处理js跨域问题方法汇总(转载)
    oncopy="document.selection.empty()"跟oncopy="return false"什么区别?
    十进制 转换为 二进制
    99%的人都理解错了HTTP中GET与POST的区别(转载
    简单封装:检测邮箱是否合法
    Xshell记录日志的方法
  • 原文地址:https://www.cnblogs.com/tomasman/p/7030432.html
Copyright © 2020-2023  润新知