1、原型模式(Prototype),用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
2、原型模式结构图
原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
3、简单代码实现
3.1、继承cloneable接口
public class ConcrerePrototype implements Cloneable {
private String name;
private String address;
public ConcrerePrototype(String name) {
// TODO Auto-generated constructor stub
this.name=name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
@Override
public String toString() {
return "ConcrerePrototype [name=" + name + ", address=" + address + "]";
}
}
3.2、调用clone方法生成新的对象
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
ConcrerePrototype cp=new ConcrerePrototype("张三");
cp.setAddress("成都市靖江区");
ConcrerePrototype cp2=(ConcrerePrototype) cp.clone();
cp2.setAddress("德阳市旌阳区");
ConcrerePrototype cp3=(ConcrerePrototype) cp.clone();
cp3.setAddress("绵阳市涪城区");
System.out.println(cp);
System.out.println(cp2);
System.out.println(cp3);
}
3.3、一般初始化的信息不发生变化的情况下,克隆是最好的办法,隐藏了对象创建的细节,又对性能大大的提高了。
4、深复制与浅复制
1、如果字段是值类型的,则对字段逐位复制,如果是引用类型,复制引用不复制对象。String类型是特殊的引用类型。
2、修改上面的例子,增加工作经历类
原型类:
public class ConcrerePrototype implements Cloneable {
private String name;
private String address;
//增加工作经历对象
private WorkExperence we;
public ConcrerePrototype(String name) {
// TODO Auto-generated constructor stub
this.name=name;
we=new WorkExperence();
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
//设置工作对象
public void setWorkEx(String workTime,String workAdress) {
we.setWorkAdress(workAdress);
we.setWorkTime(workTime);
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
@Override
public String toString() {
return "ConcrerePrototype [name=" + name + ", address=" + address + ", we=" + we + "]";
}
}
工作经历类:
public class WorkExperence {
private String workTime;
private String workAdress;
public String getWorkTime() {
return workTime;
}
public void setWorkTime(String workTime) {
this.workTime = workTime;
}
public String getWorkAdress() {
return workAdress;
}
public void setWorkAdress(String workAdress) {
this.workAdress = workAdress;
}
@Override
public String toString() {
return "WorkExperence [workTime=" + workTime + ", workAdress=" + workAdress + "]";
}
}
客户端:
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
ConcrerePrototype cp=new ConcrerePrototype("张三");
cp.setAddress("成都市靖江区");
cp.setWorkEx("2007-8-9", "成都市靖江区");
ConcrerePrototype cp2=(ConcrerePrototype) cp.clone();
cp2.setAddress("德阳市旌阳区");
cp.setWorkEx("2008-5-19", "德阳市旌阳区");
ConcrerePrototype cp3=(ConcrerePrototype) cp.clone();
cp3.setAddress("绵阳市涪城区");
cp.setWorkEx("2011-5-19", "绵阳市涪城区");
System.out.println(cp);
System.out.println(cp2);
System.out.println(cp3);
}
}
3、这就是浅复制,被复制对象的所有变量都含与原来对象相同的值,而所有其他对象的引用都仍然指向原来的对象。
4、深复制就是把引用对象的变量指向复制过的新对象,而不是原有的被引用对象。
5、解决办法:在主类中的clone方法中克隆工作经历对象;或者序列化。