Java學習筆記——設計模式之六.原型模式(淺克隆和深克隆)
阿新 • • 發佈:2017-06-17
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 privateString 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 } 2223 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學習筆記——設計模式之六.原型模式(淺克隆和深克隆)