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          *  输出:[email protected],原型,李四
16          *       [email protected],副本,李四
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          *  输出:[email protected],null,[email protected]
11          *       [email protected],null,[email protected]
12          */
13         System.out.println(c1+","+c1.getId()+","+c1.getObj());
14         System.out.println(c2+","+c2.getId()+","+c2.getObj());
15
16     }
17
18 }
时间: 2024-11-07 02:39:02

Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)的相关文章

JAVA学习笔记-----设计模式之工厂模式

1.设计模式---------->工厂模式: Sender.java package me.ele.mytest; public interface Sender {    public void send(); } 2.MailSend package me.ele.mytest; public class MailSend implements Sender {     @Override     public  void send()     {         System.out.pr

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

To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: 1 package cn.no4.proxy; 2 3 public interface IMakeMoney { 4 5 void makeMoney(); 6 } 1 package cn.no4.proxy; 2 3 public class Proxy implements IMakeMoney { 4

java学习笔记-设计模式14(策略模式)

意图 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可. public interface ICalculator { public int calculate(String exp); } public abstract class AbstractCalculator { public int[] split(String exp,String opt){ String

java学习笔记-设计模式9(代理模式)

意图 为其他对象提供一种代理以控制对这个对象的访问. public interface Sourceable { public void method(); } public class Source implements Sourceable{ @Override public void method() { System.out.println("this is original method!"); } } public class Proxy implements Source

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

模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图: 代码: 算法骨架: 1 package cn.happy.design_pattern._07templatemethod; 2 3 public abstract class AbstractClass { 4 5 public abstract void primitiveOperation1(); 6 pub

java学习笔记-设计模式20(备忘录模式)

意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到保存的状态. public class Original { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Original(String value) { this.valu

java学习笔记-设计模式15(模板方法模式)

意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 就是指:一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用 public abstract class AbstractCalculator { /*主方法,实现对本类其它方法的调用*/ public final int calcul

java学习笔记-设计模式19(命令模式)

意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作 public interface Command { public void exe(); } public class MyCommand implements Command { private Receiver receiver; public MyCommand(Receiver receiver) { this.receiver = receiver; } @Over

java学习笔记-设计模式21(状态模式)

意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. public class State { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void method1(){ System.out.println("execute the first opt!