GOF23設計模式之原型模式(prototype)

1、原型模式概述

  1.經過new產生一個對象須要很是繁瑣的數據準備和訪問權限,則可使用原型模式。html

  2.就是java中的克隆技術,以某個對象爲原型,複製出新的對象,顯然,新的對象具有原型對象的特色。java

  3.優點:效率高(直接克隆,避免了從新執行構造函數的過程)。函數

  4.克隆相似於new,可是不一樣於new。
    new建立出來的對象屬性採用默認值,克隆出來的對象屬性值徹底和原型對象相同,而且克隆出的新對象不會影響原型對象,而後,再修改克隆對象的值。測試

  是否使用原型模式比較:this

    1.若是須要建立大量不費時的對象,new的對象和clone的對象效率至關spa

    2.若是須要建立大量耗時的對象,建議使用原型模式code

2、原型模式三種實現方式

  1.淺複製:類中實現 Cloneable接口,重寫clone方法htm

  2.深複製:類中實現 Cloneable接口,重寫clone方法時將對象一塊兒克隆對象

  3.深複製:類中實現 Serializable接口,利用反序列化實現深克隆blog

  淺複製,深複製知識請點擊此處

3、使用淺複製實現原型模式

  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(克隆對象)-->少利

4、使用深複製實現原型模式(1)

  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

5、使用深複製實現原型模式(2)

  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

6、原型模式常見應用場景

  1.原型模式不多單獨出現,通常是和工廠方法模式一塊兒出現。經過clone的方法建立一個對象,而後由工廠方法提供給調用者;

  2.Spring中的bean的建立其實就是兩種:單例模式和原型模式(+工廠模式);

  3.………………

相關文章
相關標籤/搜索