原型模式精讲
原型模式是一種創(chuàng)建型模式,也是屬于創(chuàng)建對象的一種方式,像西游記里面的孫悟空吹猴毛也屬于原型模式,克隆出來了一群的猴子猴孫,還有細胞的分裂,spring中的Bean的生命周期好像有一個單例還有個原型,那個原型就是每次請求都復制一個對象出來,官方的定義是:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。在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;}@Overridepublic 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();} }返回結(jié)果:
zj 123 wahaha hello2 wahaha hello2通過上面可以看出來,p中的arr修改了值以后,person中的值也進行了修改,所以這是屬于淺克隆,淺克隆,對于被克隆的類中成員變量都是基本數(shù)據(jù)類型,可以實現(xiàn)了兩份數(shù)據(jù);被克隆的類中成員變量是對象類型,那么這個成員變量還是原來的引用,修改為新對象的值,舊對象的該對象類型的成員變量還是會變化。
深克隆
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;}@Overridepublic 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();} }返回結(jié)果:
zj 123 wahaha hello2 hello1 hello2數(shù)組中的兩個值的修改是都不會影響的,因為他們屬于兩個對象,所以上面的是屬于深克隆.從新生成了地址。但是重寫clone方法實現(xiàn)深克隆比較麻煩,要對所有是對象類型的成員變量,進行重新創(chuàng)建實例,重新賦值; 集合類會更麻煩,比如說ArrayList雖然重寫了clone(),但還是淺克隆,實現(xiàn)深克隆需要遍歷所有的model,創(chuàng)建實例,重新賦值的。
序列化實現(xiàn)深克隆
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);} }這種方式比較簡單,不用寫很多的冗余的代碼,有利于代碼的閱讀。
?
轉(zhuǎn)載于:https://www.cnblogs.com/cleveraboy/p/9738022.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
- 上一篇: 【题解】Atcoder ARC#90 F
- 下一篇: 清北学堂Day 3 游记