原型模式(Prototype)

Diy_os發表於2017-06-08

原型模式顧名思義,以一個物件為原型,進行克隆,複製操作,產生一個和原型相似的物件。下面用的例子是以中淺複製和深複製為例。

淺複製:被克隆物件的所有變數都與原來物件有相同的值,而所有的對其他物件的引用仍然指向原來的物件。

上面說的很抽象,下面透過簡單堆疊圖描述:(圖與示例程式碼相對應,man物件在person類中被引用)


深複製:被克隆物件的所有變數都與原來的物件有相同的值,除去那些引用其他物件的變數。那些引用其他物件的變數將指向被克隆過的新物件,而不再是原有的那些被引用的物件。


示例程式碼:

  1. public class Man implements Cloneable{  
  2.     private String name;  
  3.     private int age;  
  4.     Man m;  
  5.     public Man(int age,String name){  
  6.         this.age = age;  
  7.         this.name = name;  
  8.     }  
  9.     public Object clone(){  
  10.         try {  
  11.           m  = (Man) super.clone();  
  12.         } catch (CloneNotSupportedException e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.         return m;  
  16.     }  
  17.     public void  setAge(int age){  
  18.         this.age = age;  
  19.     }  
  20.     public void setName(String name){  
  21.         this.name = name;  
  22.     }  
  23.     public int getAge(){  
  24.         return age;  
  25.     }  
  26.     public String getName(){  
  27.         return name;  
  28.     }  
  29. }  
  1. public class Person implements Cloneable {  
  2.     private int age;  
  3.     private String name;  
  4.      Man man;  
  5.     String address = new String("CQ");  
  6.     public Person(int age,String name,Man man){  
  7.         this.age = age;  
  8.         this.name = name;  
  9.         this.man = man;  
  10.     }  
  11.     /* 
  12.      *淺複製 
  13.      */  
  14.     public Person clone(){  
  15.         Person person = null;  
  16.         try {  
  17.             person = (Person) super.clone();  
  18.         }catch (CloneNotSupportedException e){  
  19.             e.printStackTrace();  
  20.         }  
  21.         return person;  
  22.     }  
  23.     /* 
  24.      *深複製 
  25.      */  
  26.     public Person deepclone(){  
  27.         Person person = null;  
  28.         try{  
  29.             person = (Person)super.clone();  
  30.             person.man = (Man)person.man.clone();//同樣複製引用的物件  
  31.         }catch (CloneNotSupportedException e){  
  32.             e.printStackTrace();  
  33.         }  
  34.         return person;  
  35.     }  
  36.   
  37.     public void setAge(int age){  
  38.         this.age = age;  
  39.     }  
  40.     public void setName(String name){  
  41.         this.name = name;  
  42.     }  
  43.     public int getAge(){  
  44.         return age;  
  45.     }  
  46.     public String getName(){  
  47.         return name;  
  48.     }  
  49.     public static void main(String[] args){  
  50.         Man man = new Man(1,"Man");  
  51.         /* 
  52.          *淺複製 
  53.          */  
  54.         System.out.print("複製前Man:\n"+"age="+man.getAge()+",name="+man.getName()+"\n");  
  55.         Person person = new Person(2,"Person",man);  
  56.         System.out.print("複製前Person:\n"+"age="+person.getAge()+",name="+person.getName()+"\n");  
  57.   
  58.         Person person1 = person.clone();  
  59.   
  60.         person1.setAge(22);  
  61.         person1.setName("Person222");  
  62.         person1.man.setAge(11);  
  63.         person1.man.setName("Man11");  
  64.         System.out.print("複製前Man:\n"+"age="+man.getAge()+",name="+man.getName()+"\n");  
  65.         System.out.print("複製後Man:\n"+"age="+person1.man.getAge()+",name="+person1.man.getName()+"\n");//Man引用複製後對值得修改,影響到修改之前的值  
  66.         System.out.print("複製後Person:\n"+"age="+person1.getAge()+",name="+person1.getName()+"\n");  
  67.   
  68.       /* 
  69.        *深複製 
  70.        */  
  71.         System.out.println("=================================================");  
  72.         Man mandeep = new Man(1,"Man");  
  73.         Person persondeep = new Person(2,"Person",mandeep);  
  74.         Person person2 = person.deepclone();  
  75.         System.out.print("深複製前Man:\n"+"age="+mandeep.getAge()+",name="+mandeep.getName()+"\n");  
  76.         System.out.print("深複製前Person:\n"+"age="+person.getAge()+",name="+person.getName()+"\n");  
  77.         person2.setAge(22);  
  78.         person2.setName("Person222");  
  79.         person2.man.setAge(11);  
  80.         person2.man.setName("Man11");  
  81.         System.out.print("深複製前Man:\n"+"age="+mandeep.getAge()+",name="+mandeep.getName()+"\n");  
  82.         System.out.print("深複製後Man:\n"+"age="+man.getAge()+",name="+man.getName()+"\n");  
  83.         System.out.print("深複製後Person:\n"+"age="+person1.getAge()+",name="+person2.getName()+"\n");  
  84.     }  
  85. }  
實現物件的複製很簡單,實現Cloneable介面,然後呼叫super.clone(),即可實現。上面實現深複製時,還可以用序列化實現。注意被克隆物件與克隆出的物件是!=,但是類型別是一樣的。
關於java的深克隆和淺克隆詳細介紹可參考:http://blog.csdn.net/pony_maggie/article/details/52091588

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29876893/viewspace-2140453/,如需轉載,請註明出處,否則將追究法律責任。

相關文章