原型模式:
原型模式是一种创建型模式,通过复制已存在的实例来获得新的实例,而不是新建实例。被复制的实例就是所称的原型,这个原型是可定制的,短时间创建大量对象时,可以考虑使用原型模式
Tip:原型模式中的拷贝分为浅拷贝和深拷贝:
浅拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象。
深拷贝:对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制。
类图:
应用场景:
原型模式很少单独出现,一般利用工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
spring中bean的创建实际就两种:单例模式和原型模式。
应用实例:
Demo1:浅拷贝
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 }
深拷贝Demo2:
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 }
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 }
Demo3:通过序列化实现深拷贝
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 }