标签:
原型模式
原型模式其实就是拷贝,假设已知对象A,对象B为 A的拷贝,那么B应该具有和A一样的数据。我们还是以造人为例。
(1) 浅克隆
Person.java
package prototype03;
import java.util.List;
public class Person implements Cloneable{
private String name = null;
private int age = 0;
private String sex = null;
private List<String> friends = null;
public List<String> getFriends() {
return friends;
}
public void setFriends(List<String> friends) {
this.friends = friends;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Person clone(){
try {
return (Person)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
先分析一下这个类,首先Person.java实现了Cloneable接口,关于Cloneable接口的详细信息请自己补充,总之,我们在这里只需要知道该接口里面有一个clone方法,而Person类里面也重写了clone方法,其中clone方法也是Person.java的核心方法,原型模式也是通过clone来实现的。
我们先来看一下运行结果,看一看Person.java是如何实现自身复制的
package prototype03;
import java.util.ArrayList;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
Person person1 = new Person();
List<String> friends = new ArrayList<String>();
friends.add("james");
friends.add("Yao");
person1.setFriends(friends);
Person person2 = person1.clone();
System.out.println(person1.getFriends());
System.out.println(person2.getFriends());
friends.add("Mike");
person1.setFriends(friends);
System.out.println(person2.getFriends());
}
}
运行结果:
[james, Yao]
[james, Yao]
[james, Yao, Mike]
对于运行结果,有些同学肯定会有疑惑,为什么person2的friends里面会包含Mike呢?我们 在程序中明明修改的是person1,这是为什么呢?其实这里牵扯到了内存的相关知识,这里不便详述,请自行到网上搜索,但是这并不影响我们讲解原型模式,你只要知道,这种是浅克隆就可以了。并且请带着这个疑问,一起来了解深克隆是怎样的吧。
(2) 深克隆
话不多少,先贴代码。
Person.java
package prototype04;
import java.util.ArrayList;
import java.util.List;
public class Person implements Cloneable{
private String name = null;
private int age = 0;
private String sex = null;
private List<String> friends = null;
public List<String> getFriends() {
return friends;
}
public void setFriends(List<String> friends) {
this.friends = friends;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Person clone(){
try {
Person person = (Person)super.clone();
List<String> friends = new ArrayList<String>();
for(String friend:this.getFriends()){
friends.add(friend);
}
person.setFriends(friends);
return person;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
测试程序:
package prototype04;
import java.util.ArrayList;
import java.util.List;
//深克隆,完全克隆所有的属性,引用的对象也完全的重新new了一遍
public class MainClass {
public static void main(String[] args) {
Person person1 = new Person();
List<String> friends = new ArrayList<String>();
friends.add("james");
friends.add("Yao");
person1.setFriends(friends);
Person person2 = person1.clone();
System.out.println(person1.getFriends());
System.out.println(person2.getFriends());
friends.add("Mike");
person1.setFriends(friends);
System.out.println(person1.getFriends());
System.out.println(person2.getFriends());
}
}
测试结果:
[james, Yao]
[james, Yao]
[james, Yao, Mike]
[james, Yao]
OK,看完了运行结果,估计会有一种顿然开悟的感觉,其实我们的代码只改了几句,就是我们在浅克隆的基础上,添加了下面几句
List<String> friends = new ArrayList<String>();
for(String friend:this.getFriends()){
friends.add(friend);
}
person.setFriends(friends);
我们重新new了ArrayList,也就是说如果对象A中的属性包含其他的对象(自定义对象、集合……),那么浅克隆仅仅是把对象的引用给复制了,而不会重新的构造出一个新的对象。但是深克隆则会把A完完全全的给重新构造一遍,包括A里面所有的属性,这就是两者的区别。
标签:
原文地址:http://www.cnblogs.com/magicy/p/4631792.html