原型模式

原型模式:

   原型模式是一种创建型模式,通过复制已存在的实例来获得新的实例,而不是新建实例。被复制的实例就是所称的原型,这个原型是可定制的,短时间创建大量对象时,可以考虑使用原型模式

Tip:原型模式中的拷贝分为浅拷贝和深拷贝:

浅拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。

深拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制。

 

类图:

 

 

应用场景:
原型模式很少单独出现,一般利用工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
spring中bean的创建实际就两种:单例模式和原型模式。

应用实例:

Demo1:浅拷贝

 1 package prototype.domain;
 2 
 3 import java.io.Serializable;
 4 import java.util.Date;
 5 
 6 public class Student implements Cloneable,Serializable{
 7     /**
 8      * 
 9      */
10     private static final long serialVersionUID = 1L;
11     private String sname;
12     private int   age;
13     private Date  birthday;
14     
15     public Student ()
16     {
17         
18     }
19     
20     public Student(String sname, int age, Date birthday)
21     {
22         super();
23         this.sname = sname;
24         this.age = age;
25         this.birthday = birthday;
26     }
27     
28     @Override
29     public Object clone() throws CloneNotSupportedException
30     {
31         Object obj = super.clone();
32             
33         return obj;
34     }
35     
36     public String getSname() {
37         return sname;
38     }
39     public void setSname(String sname) {
40         this.sname = sname;
41     }
42     public int getAge() {
43         return age;
44     }
45     public void setAge(int age) {
46         this.age = age;
47     }
48     public Date getBirthday() {
49         return birthday;
50     }
51     public void setBirthday(Date birthday) {
52         this.birthday = birthday;
53     }
54 
55     @Override
56     public String toString() {
57         return "Student [sname=" + sname + ", age=" + age + ", birthday="
58                 + birthday + "]";
59     }
60 
61     @Override
62     public int hashCode() {
63         final int prime = 31;
64         int result = 1;
65         result = prime * result + age;
66         result = prime * result
67                 + ((birthday == null) ? 0 : birthday.hashCode());
68         result = prime * result + ((sname == null) ? 0 : sname.hashCode());
69         return result;
70     }
71 
72     @Override
73     public boolean equals(Object obj) {
74         if (this == obj)
75             return true;
76         if (obj == null)
77             return false;
78         if (getClass() != obj.getClass())
79             return false;
80         Student other = (Student) obj;
81         if (age != other.age)
82             return false;
83         if (birthday == null) {
84             if (other.birthday != null)
85                 return false;
86         } else if (!birthday.equals(other.birthday))
87             return false;
88         if (sname == null) {
89             if (other.sname != null)
90                 return false;
91         } else if (!sname.equals(other.sname))
92             return false;
93         return true;
94     }
95     
96     
97     
98 }
View Code

深拷贝Demo2:

  1 package prototype.domain;
  2 
  3 import java.io.Serializable;
  4 import java.util.Date;
  5 
  6 public class Student implements Cloneable,Serializable{
  7     /**
  8      * 
  9      */
 10     private static final long serialVersionUID = 1L;
 11     private String sname;
 12     private int   age;
 13     private Date  birthday;
 14     
 15     public Student ()
 16     {
 17         
 18     }
 19     
 20     public Student(String sname, int age, Date birthday)
 21     {
 22         super();
 23         this.sname = sname;
 24         this.age = age;
 25         this.birthday = birthday;
 26     }
 27     
 28     @Override
 29     public Object clone() throws CloneNotSupportedException
 30     {
 31         Object obj = super.clone();
 32         
 33         //实现深复制功能(deep Clone)
 34         Student s = (Student)obj;
 35         //把属性也进行克隆!
 36         s.birthday = (Date)this.birthday.clone();
 37         
 38         return obj;
 39     }
 40     
 41     public String getSname() {
 42         return sname;
 43     }
 44     public void setSname(String sname) {
 45         this.sname = sname;
 46     }
 47     public int getAge() {
 48         return age;
 49     }
 50     public void setAge(int age) {
 51         this.age = age;
 52     }
 53     public Date getBirthday() {
 54         return birthday;
 55     }
 56     public void setBirthday(Date birthday) {
 57         this.birthday = birthday;
 58     }
 59 
 60     @Override
 61     public String toString() {
 62         return "Student [sname=" + sname + ", age=" + age + ", birthday="
 63                 + birthday + "]";
 64     }
 65 
 66     @Override
 67     public int hashCode() {
 68         final int prime = 31;
 69         int result = 1;
 70         result = prime * result + age;
 71         result = prime * result
 72                 + ((birthday == null) ? 0 : birthday.hashCode());
 73         result = prime * result + ((sname == null) ? 0 : sname.hashCode());
 74         return result;
 75     }
 76 
 77     @Override
 78     public boolean equals(Object obj) {
 79         if (this == obj)
 80             return true;
 81         if (obj == null)
 82             return false;
 83         if (getClass() != obj.getClass())
 84             return false;
 85         Student other = (Student) obj;
 86         if (age != other.age)
 87             return false;
 88         if (birthday == null) {
 89             if (other.birthday != null)
 90                 return false;
 91         } else if (!birthday.equals(other.birthday))
 92             return false;
 93         if (sname == null) {
 94             if (other.sname != null)
 95                 return false;
 96         } else if (!sname.equals(other.sname))
 97             return false;
 98         return true;
 99     }
100     
101     
102     
103 }
View Code
 1 package prototype.service;
 2 
 3 import java.util.Date;
 4 
 5 import prototype.domain.Student;
 6 
 7 public class DeepClientTest {
 8 
 9     public static void main(String[] args) throws CloneNotSupportedException {
10         // TODO Auto-generated method stub
11         Date date = new Date(12312321331L);
12         Student s1 = new Student("少利",12, date);
13         Student s2 = (Student)s1.clone();   //实现深复制。s2对象的birthday是一个新对象!
14         
15         
16         System.out.println(s1);
17         System.out.println(s1.getSname());
18         System.out.println(s1.getBirthday());
19         
20         date.setTime(23432432423L);
21         
22         System.out.println(s1.getBirthday());
23         
24         
25         s2.setSname("多利");
26         System.out.println(s2);
27         System.out.println(s2.getSname());
28         System.out.println(s2.getBirthday());
29     }
30 
31 }
View Code

Demo3:通过序列化实现深拷贝

 1 package prototype.service;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.IOException;
 6 import java.io.ObjectInputStream;
 7 import java.io.ObjectOutputStream;
 8 import java.util.Date;
 9 
10 import prototype.domain.Student;
11 
12 public class ClientSerialTet {
13 
14     public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
15         // TODO Auto-generated method stub
16         // TODO Auto-generated method stub
17         Date date = new Date(12312321331L);
18         Student s1 = new Student("少利",12, date);
19         //Student s2 = (Student)s1.clone();   //实现深复制。s2对象的birthday是一个新对象!
20 //        使用序列化和反序列化实现深复制
21         ByteArrayOutputStream bos = new ByteArrayOutputStream();
22         ObjectOutputStream    oos = new ObjectOutputStream(bos);
23         oos.writeObject(s1);
24         byte[] bytes = bos.toByteArray();
25         
26         ByteArrayInputStream  bis = new ByteArrayInputStream(bytes);
27         ObjectInputStream      ois = new ObjectInputStream(bis);
28         
29         Student s2 = (Student) ois.readObject();   //克隆好的对象!
30         
31         System.out.println(s1);
32         System.out.println(s1.getSname());
33         System.out.println(s1.getBirthday());
34         
35         date.setTime(23432432423L);
36         
37         System.out.println(s1.getBirthday());
38         
39         
40         s2.setSname("多利");
41         System.out.println(s2);
42         System.out.println(s2.getSname());
43         System.out.println(s2.getBirthday());
44     }
45 
46 }
View Code

 

posted on 2015-11-06 20:49  ilinux_one  阅读(255)  评论(0编辑  收藏  举报

导航