標籤:div hello app 成員 種類 通過 test att 執行個體
原型模式是一種建立型模式,也是屬於建立對象的一種方式,像西遊記裡面的孫悟空吹猴毛也屬於原型模式,複製出來了一群的猴子猴孫,還有細胞的分裂,spring中的Bean的生命週期好像有一個單例還有個原型,那個原型就是每次請求都複製一個對象出來,官方的定義是:用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。在java裡面有一個clone的方法是屬於Object類的,java裡的複製有淺複製和深複製之分,下面通過代碼來看看:
淺複製
package pattern.prototype;public class Person implements Cloneable { public String name; public String pass; public String[] arr; public Person(String name,String pass,String[] arr){ this.name=name; this.pass=pass; this.arr=arr; } @Override public Object clone() throws CloneNotSupportedException { Person person=(Person)super.clone();return person; }}
package pattern.prototype;public class Test { public static void main(String[] args) throws CloneNotSupportedException { String[] arr={"hello1","hello2"}; Person person=new Person("zj","123",arr); Person p=(Person)person.clone(); System.out.println(p.name); System.out.println(p.pass); p.name="jack"; p.pass="666"; p.arr[0]="wahaha"; for (String favor : p.arr) { System.out.print(favor + " "); } System.out.println(); for (String favor : person.arr) { System.out.print(favor + " "); } System.out.println(); }}
返回結果:
zj123wahaha hello2 wahaha hello2
通過上面可以看出來,p中的arr修改了值以後,person中的值也進行了修改,所以這是屬於淺複製,淺複製,對於被複製的類中成員變數都是基礎資料型別 (Elementary Data Type),可以實現了兩份資料;被複製的類中成員變數是物件類型,那麼這個成員變數還是原來的引用,修改為新對象的值,舊對象的該物件類型的成員變數還是會變化。
深複製
package pattern.prototype;public class Person implements Cloneable { public String name; public String pass; public String[] arr; public Person(String name,String pass,String[] arr){ this.name=name; this.pass=pass; this.arr=arr; } @Override public Object clone() throws CloneNotSupportedException { Person person=(Person)super.clone(); person.arr=arr.clone(); return person; }}
package pattern.prototype;public class Test { public static void main(String[] args) throws CloneNotSupportedException { String[] arr={"hello1","hello2"}; Person person=new Person("zj","123",arr); Person p=(Person)person.clone(); System.out.println(p.name); System.out.println(p.pass); p.name="jack"; p.pass="666"; p.arr[0]="wahaha"; for (String favor : p.arr) { System.out.print(favor + " "); } System.out.println(); for (String favor : person.arr) { System.out.print(favor + " "); } System.out.println(); }}
返回結果:
zj123wahaha hello2 hello1 hello2
數組中的兩個值的修改是都不會影響的,因為他們屬於兩個對象,所以上面的是屬於深複製.從新產生了地址。但是重寫clone方法實現深複製比較麻煩,要對所有是物件類型的成員變數,進行重新建立執行個體,重新賦值; 集合類會更麻煩,比如說ArrayList雖然重寫了clone(),但還是淺複製,實現深複製需要遍曆所有的model,建立執行個體,重新賦值的。
序列化實現深複製
package pattern.prototype;import java.io.*;public class Apple implements,Serializable { public String name; public int age; public Apple(String name,int age){ this.name=name; this.age=age; } public Object deepClone(Object obj) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; ObjectInputStream ois = null; try { oos = new ObjectOutputStream(bos); oos.writeObject(obj); ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { try { bos.close(); oos.close(); ois.close(); } catch (Exception e) { e.printStackTrace(); } } return null; } public static void main(String[] args) { Apple apple=new Apple("aaa",18); Apple apple1 = (Apple) apple.deepClone(apple); System.out.println(apple1==apple); }}
這種方式比較簡單,不用寫很多的冗餘的代碼,有利於代碼的閱讀。
原型模式精講