原型模式

定义

原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原理

将一个原型对象传给那个要发动创建的对象,这个对象通过请求原型对象拷贝它们自己来实施创建。克隆对象和原对象具有相同的属性和状态。

类图

在这里插入图片描述

优点
  1. 当创建类的新实例时的代价更大时,使用原型模式复制一个已有的实例可以提高创建新实例的效率。
  2. 可以动态的保存当前对象的状态。在运行时可以随时使用对象流保存当前对象的一个复制品。
  3. 可以在运行时创建新的对象,而无需创建一系列类和继承结构。
  4. 可以动态的添加、删除原型的复制品。
缺点

每个类必须配备一个克隆方法,不容易对已有的类进行改造。

适用
  1. 系统应该独立于产品创建、构成、表示时。
  2. 实例化的类在运行时指定。
  3. 避免创建一个与产品类层次平行的工厂类层次时。
  4. 当一个类的实例只能有几个不同状态组合中的一种时。
深拷贝和浅拷贝

浅拷贝是只拷贝引用(引用类型),源对象指向同一个,改变克隆对象的值时,原对象也变了。深拷贝值和引用都拷贝,改变克隆对象并不会影响原对象。但对于值类型(基本类型)来说,浅拷贝和深拷贝没有区别,原对象和克隆对象互不影响。

public class WorkExperience implements Serializable {
	private static final long serialVersionUID = 1L;

    private String workDate;
    private String workCompany;

    public String getWorkDate() {
	    return workDate;
    }

    public WorkExperience setWorkDate(String workDate) {
	    this.workDate = workDate;
	    return this;
    }

    public String getWorkCompany() {
	    return workCompany;
    }

    public WorkExperience setWorkCompany(String workCompany) {
	    this.workCompany = workCompany;
	    return this;
    }


public class Resume implements Cloneable, Serializable{
	private static final long serialVersionUID = -4410449301166191440L;
	
	private String name;
    private String gender;
    private int age;

    // 引用“工作经历”对象,为演示深度拷贝和浅度拷贝而用
    private WorkExperience workExperience;

    public Resume() {
    	// 在“简历”类实例化时,同时实例化“工作经历”类
    	workExperience = new WorkExperience();
    }

    public void display() {
		System.out.println(this.getName() + " " + this.getGender() + " "
			+ this.getAge() + "\n工作经历: "
			+ this.getWorkExperience().getWorkDate() + " "
			+ this.getWorkExperience().getWorkCompany());
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
    	return super.clone();
    }

    // 通过对象序列化,实现深度拷贝
    public Object deepClone() throws IOException, ClassNotFoundException {
    	// 将对象写入流内
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(this);

		// 从流内读出对象
		ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
			bos.toByteArray()));
		return ois.readObject();

    }

    public String getName() {
    	return name;
    }

    public Resume setName(String name) {
    	this.name = name;
    	return this;
    }

    public String getGender() {
    	return gender;
    }

    public Resume setGender(String gender) {
    	this.gender = gender;
    	return this;
    }

    public int getAge() {
    	return age;
    }

    public Resume setAge(int age) {
    	this.age = age;

	return this;
    }

    public WorkExperience getWorkExperience() {
    	return workExperience;
    }

    public void setWorkExperience(String workDate, String workCompany) {
    	workExperience.setWorkDate(workDate);
    	workExperience.setWorkCompany(workCompany);
    }

}
public class PrototypeClient {
	public static void shallowCopy() throws CloneNotSupportedException {
		Resume aResume = new Resume();
		aResume.setName("大鸟 ").setGender("男 ").setAge(25);
		aResume.setWorkExperience("1999-2002, ", "XX公司");

		Resume bResume = (Resume) aResume.clone();
		bResume.setWorkExperience("1999-2002, ", "YY公司");

		Resume cResume = (Resume) aResume.clone();
		cResume.setWorkExperience("1999-2002, ", "ZZ公司");

		System.out.println(">>>>>>浅度拷贝:");
		aResume.display();
		bResume.display();
		cResume.display();
	}

	public static void deepCopy() throws CloneNotSupportedException,
		    ClassNotFoundException, IOException {
		Resume aResume = new Resume();
		aResume.setName("大鸟 ").setGender("男 ").setAge(25);
		aResume.setWorkExperience("1999-2002, ", "XX公司");

		Resume bResume = (Resume) aResume.deepClone();
		bResume.setWorkExperience("1999-2002, ", "YY公司");

		Resume cResume = (Resume) aResume.deepClone();
		cResume.setWorkExperience("1999-2002, ", "ZZ公司");

		System.out.println(">>>>>>深度拷贝:");
		aResume.display();
		bResume.display();
		cResume.display();
	}

	public static void main(String[] args) throws CloneNotSupportedException,
		    ClassNotFoundException, IOException {
		// 浅度拷贝
		shallowCopy();
		System.out.println("==================================");
		// 深度拷贝
		deepCopy();
	 }
}

上一篇: 抽象工厂方法模式
下一篇: 备忘录模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值