1. 程式人生 > >Java學習筆記——設計模式之六.原型模式(淺克隆和深克隆)

Java學習筆記——設計模式之六.原型模式(淺克隆和深克隆)

catch 新的 att over 引用變量 col logs implement pri

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 }

Java學習筆記——設計模式之六.原型模式(淺克隆和深克隆)