原型模式

原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。它其实就是从一个对象再创建另一个可定制的对象,而且不需要知道任何创建的细节。

1、现实Cloneable接口的抽象类Prototype

public abstract class Prototype implements Cloneable
{
public String id;
public Prototype(String id)
{
    this.id=id;
}
public String getId()
{
    return id;
}
public abstract Prototype Clone() throws Exception;//关键的clone方法
}

2、继承prototype的具体类Concreteprorotype

public class ConcretePrototype extends Prototype
{
   public ConcretePrototype(String id)
	{
		super(id);
	}
   public Prototype Clone() throws Exception
   {
	   return (Prototype)this.clone();
   }
}
3、客户端类

public class Client
{

	public static void main(String[] args) throws Exception
	{
     ConcretePrototype p1=new ConcretePrototype("1");
     ConcretePrototype c1=(ConcretePrototype)p1.Clone();
     System.out.println("c1:"+c1.id);
	}

}

实例应用,简历复制

1、实现Cloneable的简历类

public class Resume implements Cloneable
{
private String name;
private String sex;
private String age;
private WorkExperience work;
public Resume(String name)
{
	this.name=name;
	work=new WorkExperience();
}
public void setPersonalInfo(String sex,String age)
{
	this.sex=sex;
	this.age=age;
}
public void setWorkExperience(String workDate,String workCompany)
{
	work.WorkDate=workDate;
	work.WorkCompany=workCompany;
}
public void display()
{
	System.out.println("name:"+name+":sex:"+sex+":age:"+age);
	System.out.println("workDate:"+work.WorkDate+":workCompany:"+work.WorkCompany);
}
public Object Clone() throws Exception
{
	return this.clone();
}
}
2、WorkExperience类实现

public class WorkExperience
{
private String workDate;
public String WorkDate;
private String workCompany;
public String WorkCompany;
public String getWorkDate()
{
	return workDate;
}
public void setWorkDate(String workDate)
{
	this.workDate = workDate;
}
public String getWorkCompany()
{
	return workCompany;
}
public void setWorkCompany(String workCompany)
{
	this.workCompany = workCompany;
}
}
3、客户端类

public class Client
{
public static void main(String[] args) throws Exception
{
    Resume a=new Resume("A");
    a.setPersonalInfo("female","20");
    a.setWorkExperience("2010-2011","xx公司");
    Resume b=(Resume)a.Clone();
    b.setWorkExperience("2010-2011","yy公司");
    a.display();
    b.display();
}
}

预测结果:

name:A:sex:female:age:20
workDate:2010-2011:workCompany:xx公司
name:A:sex:female:age:20
workDate:2010-2011:workCompany:yy公司

实际结果:


原因:涉及到浅复制与深复制的概念

clone()的方法,如果字段是值类型的,则对该字段进行逐位复制。如果字段是引用类型的,则复制引用不复制引用的对象,也就是说复制后的引用和之前的引用是指向同一个地方的。在这里面因为WorkExperience work是对象引用,那么它的数据不会被复制过来,只会复制引用。这就是浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制就是把引用对象的变量指向复制过后的新变量,而不是原有的被引用的对象

代码修改:

1、WorkExperience代码修改

public class WorkExperience <span style="color:#FF6666;">implements Cloneable</span>//实现Cloneable接口
{
private String workDate;
public String WorkDate;
private String workCompany;
public String WorkCompany;
public String getWorkDate()
{
    return workDate;
}
public void setWorkDate(String workDate)
{
    this.workDate = workDate;
}
public String getWorkCompany()
{
    return workCompany;
}
public void setWorkCompany(String workCompany)
{
    this.workCompany = workCompany;
}
<span style="color:#FF6666;">public Object Clone() throws Exception<span style="color:#000000;">//复制方法</span>
{
    return this.clone();
    
}</span>
}

2、Resume代码修改

public class Resume implements Cloneable
{
private String name;
private String sex;
private String age;
<span style="color:#FF6666;">private WorkExperience work;</span>
public Resume(String name)
{
	this.name=name;
	work=new WorkExperience();
}
@SuppressWarnings("unused")
<span style="color:#FF6666;">private Resume(WorkExperience work) throws Exception
{
	this.work=(WorkExperience)work.Clone();
}</span>
public void setPersonalInfo(String sex,String age)
{
	this.sex=sex;
	this.age=age;
}
public void setWorkExperience(String workDate,String workCompany)
{
	work.WorkDate=workDate;
	work.WorkCompany=workCompany;
}
public void display()
{
	System.out.println("name:"+name+":sex:"+sex+":age:"+age);
	System.out.println("workDate:"+work.WorkDate+":workCompany:"+work.WorkCompany);
}
<span style="color:#FF6666;">public Object Clone() throws Exception
{
	Resume resume=new Resume(this.work);//调用私有的构造方法,让工作经历克隆完成,然后再给这个简历对象的相关字段复制,最后返回一个深复制的简历对象
	resume.sex=this.sex;
	resume.name=this.name;
	resume.age=this.age;
	return resume;
}</span>
}
运行结果如下:


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值