1.經過new產生一個對象須要很是繁瑣的數據準備和訪問權限,則可使用原型模式。html
2.就是java中的克隆技術,以某個對象爲原型,複製出新的對象,顯然,新的對象具有原型對象的特色。java
3.優點:效率高(直接克隆,避免了從新執行構造函數的過程)。函數
4.克隆相似於new,可是不一樣於new。
new建立出來的對象屬性採用默認值,克隆出來的對象屬性值徹底和原型對象相同,而且克隆出的新對象不會影響原型對象,而後,再修改克隆對象的值。測試
是否使用原型模式比較:this
1.若是須要建立大量不費時的對象,new的對象和clone的對象效率至關spa
2.若是須要建立大量耗時的對象,建議使用原型模式code
1.淺複製:類中實現 Cloneable接口,重寫clone方法htm
2.深複製:類中實現 Cloneable接口,重寫clone方法時將對象一塊兒克隆對象
3.深複製:類中實現 Serializable接口,利用反序列化實現深克隆blog
1.使用原型模式克隆多利羊
1 /** 2 * 原型模式(淺克隆) 3 * @author CL 4 * 5 */ 6 public class Sheep implements Cloneable { 7 private String name; 8 9 public Object clone() throws CloneNotSupportedException { 10 return super.clone(); 11 } 12 13 public Sheep() { 14 } 15 16 public Sheep(String name) { 17 this.name = name; 18 } 19 20 public String getName() { 21 return name; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 28 }
2.測試
1 public class TestSheep { 2 3 public static void main(String[] args) throws Exception { 4 Sheep s1 = new Sheep("多利"); 5 Sheep s2 = (Sheep) s1.clone(); //克隆對象 6 7 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()); 8 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()); 9 10 s2.setName("少利"); //對克隆對象修改,不影響原對象的屬性值 11 12 System.out.println("\n--------修改克隆對象的屬性值後---------\n"); 13 14 15 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()); 16 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()); 17 } 18 19 }
控制檯輸出:
366712642(原型對象)-->多利 1829164700(克隆對象)-->多利 --------修改克隆對象的屬性值後--------- 366712642(原型對象)-->多利 1829164700(克隆對象)-->少利
1.使用原型模式克隆多利羊
1 import java.util.Date; 2 3 /** 4 * 原型模式(深克隆) 5 * @author CL 6 * 7 */ 8 public class Sheep implements Cloneable { 9 private String name; 10 11 private Birthday birthday; 12 13 public Object clone() throws CloneNotSupportedException { 14 Sheep s = (Sheep) super.clone(); //克隆對象 15 s.birthday = (Birthday) this.birthday.clone(); 16 return s; 17 } 18 19 public Sheep() { 20 } 21 22 public Sheep(String name, Birthday birthday) { 23 this.name = name; 24 this.birthday = birthday; 25 } 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public Birthday getBirthday() { 36 return birthday; 37 } 38 39 public void setBirthday(Birthday birthday) { 40 this.birthday = birthday; 41 } 42 43 44 } 45 46 class Birthday implements Cloneable { 47 private Date birthday; 48 49 protected Object clone() throws CloneNotSupportedException { 50 return super.clone(); 51 } 52 53 public Birthday() { 54 } 55 56 public Birthday(Date birthday) { 57 this.birthday = birthday; 58 } 59 60 public Date getBirthday() { 61 return birthday; 62 } 63 64 public void setBirthday(Date birthday) { 65 this.birthday = birthday; 66 } 67 }
2.測試
1 import java.util.Date; 2 3 /** 4 * 測試原型模式(深克隆) 5 * @author CL 6 * 7 */ 8 public class TestSheep { 9 10 public static void main(String[] args) throws Exception { 11 Birthday date = new Birthday(new Date(5456464L)); 12 Sheep s1 = new Sheep("多利", date); 13 Sheep s2 = (Sheep) s1.clone(); //克隆對象 14 15 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()+"-->"+s1.getBirthday().getBirthday()); 16 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()+"-->"+s2.getBirthday().getBirthday()); 17 18 date.setBirthday(new Date()); //對克隆對象修改,原對象的屬性值改變 19 20 System.out.println("\n--------修改克隆對象的屬性值後---------\n"); 21 22 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()+"-->"+s1.getBirthday().getBirthday()); 23 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()+"-->"+s2.getBirthday().getBirthday()); 24 } 25 26 }
控制檯輸出:
366712642(原型對象)-->多利-->Thu Jan 01 09:30:56 CST 1970 1550089733(克隆對象)-->多利-->Thu Jan 01 09:30:56 CST 1970 366712642(原型對象)-->多利-->Fri Dec 29 17:03:26 CST 2017 1550089733(克隆對象)-->多利-->Thu Jan 01 09:30:56 CST 1970
1.使用原型模式克隆多利羊
1 import java.io.Serializable; 2 import java.util.Date; 3 4 /** 5 * 原型模式(利用反序列化實現深克隆) 6 * @author CL 7 * 8 */ 9 public class Sheep implements Serializable { 10 private String name; 11 12 private Birthday birthday; 13 14 public Sheep() { 15 } 16 17 public Sheep(String name, Birthday birthday) { 18 this.name = name; 19 this.birthday = birthday; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public Birthday getBirthday() { 31 return birthday; 32 } 33 34 public void setBirthday(Birthday birthday) { 35 this.birthday = birthday; 36 } 37 38 } 39 40 class Birthday implements Serializable { 41 private Date birthday; 42 43 public Birthday() { 44 } 45 46 public Birthday(Date birthday) { 47 this.birthday = birthday; 48 } 49 50 public Date getBirthday() { 51 return birthday; 52 } 53 54 public void setBirthday(Date birthday) { 55 this.birthday = birthday; 56 } 57 }
2.測試
1 import java.io.ByteArrayInputStream; 2 import java.io.ByteArrayOutputStream; 3 import java.io.ObjectInputStream; 4 import java.io.ObjectOutputStream; 5 import java.util.Date; 6 7 /** 8 * 測試原型模式(利用反序列化實現深克隆) 9 * @author CL 10 * 11 */ 12 public class TestSheep { 13 14 public static void main(String[] args) throws Exception { 15 Birthday date = new Birthday(new Date(5456464L)); 16 Sheep s1 = new Sheep("多利", date); 17 18 //利用反序列化實現深克隆 19 //1. 序列化 20 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 21 ObjectOutputStream oos = new ObjectOutputStream(bos); 22 oos.writeObject(s1); 23 byte[] bytes = bos.toByteArray(); 24 25 //2. 反序列化 26 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 27 ObjectInputStream ois = new ObjectInputStream(bis); 28 Sheep s2 = (Sheep) ois.readObject(); 29 30 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()+"-->"+s1.getBirthday().getBirthday()); 31 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()+"-->"+s2.getBirthday().getBirthday()); 32 33 date.setBirthday(new Date()); //對克隆對象修改,原對象的屬性值改變 34 35 System.out.println("\n--------------------修改克隆對象的屬性值後---------------------\n"); 36 37 System.out.println(s1.hashCode()+"(原型對象)-->"+s1.getName()+"-->"+s1.getBirthday().getBirthday()); 38 System.out.println(s2.hashCode()+"(克隆對象)-->"+s2.getName()+"-->"+s2.getBirthday().getBirthday()); 39 } 40 41 }
控制檯輸出:
1442407170(原型對象)-->多利-->Thu Jan 01 09:30:56 CST 1970 1173230247(克隆對象)-->多利-->Thu Jan 01 09:30:56 CST 1970 --------------------修改克隆對象的屬性值後--------------------- 1442407170(原型對象)-->多利-->Fri Dec 29 17:11:21 CST 2017 1173230247(克隆對象)-->多利-->Thu Jan 01 09:30:56 CST 1970
1.原型模式不多單獨出現,通常是和工廠方法模式一塊兒出現。經過clone的方法建立一個對象,而後由工廠方法提供給調用者;
2.Spring中的bean的建立其實就是兩種:單例模式和原型模式(+工廠模式);
3.………………