原型模式
原型模式实际上就是一种克隆对象的方法。
什么时候需要用到原型模式呐?当一个对象获取了多个状态,这时候你如果再去创建新的对象,再去获取状态,会很浪费资源和时间,这个时候用克隆就非常合适。或者当你要实例化一个对象时,但你并不知道所属的具体类的时候。
Prototype
为抽象原型类,声明了clone()方法的接口或者基类
ConcretePrototype
为具体的实现类,实现抽象原型类的clone方法,更加具体。
浅拷贝和深拷贝
在原型模式中,我们谈到了克隆
我们的克隆分为,浅拷贝和深拷贝
例如:
当拷贝对象只包含简单数据类型或者String时,就直接将这些字段复制到对象中。
但是涉及到,拷贝对象中中包含了对其他对象的引用时,就体现了浅拷贝和深拷贝的区别。浅拷贝和深拷贝的不同是对于引用的处理不同。当拷贝的对象中包含了对其他对象的引用时,浅拷贝直接将对象中的引用型字段复制给它的一个引用给目标对象,而深拷贝会在新对象中创建一个新的和源对象中对应字段相同的字段。
就比如:一个人对象,包含了一个心脏对象和两个胳膊对象,我们拷贝一个人时候,我们应给用深拷贝,在拷贝一个人时,应该创建新的心脏对象和胳膊对象。因为不同的人不能共用心脏和胳膊。
浅拷贝
创建原型Prototype接口
public interface Prototype {
Prototype clone();
}
需要克隆的具体类
import java.util.List;
public class ConcretePrototypeA implements Prototype {
private int age;
private String name;
private List hobbies;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public List getHobbies(){
return hobbies;
}
public void setHobbies(List hobbies){
this.hobbies = hobbies;
}
@Override
public ConcretePrototypeA clone(){
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
concretePrototype.setAge(this.age);
concretePrototype.setName(this.name);
concretePrototype.setHobbies(this.hobbies);
return concretePrototype;
}
}
Client类
public class Client {
private Prototype prototype;
public Client(Prototype prototype){
this.prototype = prototype;
}
public Prototype starClone(Prototype concretePrototype){
return concretePrototype.clone();
}
}
测试
import java.util.ArrayList;
import java.util.List;
public class PrototypeTest {
public static void main(String arg[]){
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
concretePrototype.setAge(18);
concretePrototype.setName("原型");
List<String> hobbies = new ArrayList<String>();
hobbies.add("篮球");
concretePrototype.setHobbies(hobbies);
System.out.println(concretePrototype);
Client client = new Client(concretePrototype);
ConcretePrototypeA concretePrototypeClone = (ConcretePrototypeA) client.starClone(concretePrototype);
System.out.println("两个对象比较:" + (concretePrototype.getHobbies() == concretePrototypeClone.getHobbies()));
}
}
结果: