设计模式之原型模式(prototype)

我们先看生活的一个例子: 我手上有一份文档,且只有一份,刚好我的朋友也想要,这个时候我又不想我把原件给他 。在没有打印机之前,肯定是要抄一份给他。但是这个抄就慢,而且还有可能抄错。

怎么办呢?

答案就是打印机出现了,有的打印机,我们直接打印一份给他,完美解决问题!

理解了这个,我们切回正题,在编程的时候,我们往往会遇到大对象,每次初始化过程非常慢,因此我们的做法就是直接复制这个对象,这样就减少了初始化过程,加快效率!

原型模式相关概念

  • 浅拷贝 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象
  • 深拷贝 把引用对象的变量指向复制过的新对象,而不是原来被引用的对象

原型模式应用场景

  • 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等;
  • 通过 new 产生一个对象需要非常繁琐的数据准备;
  • 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时;

Java 原型模式示例

public interface MyPrototype {
	MyPrototype getShallowCloneInstance();
	MyPrototype getDeepCloneInstance();
}

public class Title implements Serializable{
}

public class Word implements MyPrototype , Serializable{

	private static final long serialVersionUID = 1L;

	private Title title;

	public Title getTitle() {
		return title;
	}

	public void setTitle(Title title) {
		this.title = title;
	}

	@Override
	public MyPrototype getShallowCloneInstance() {
		Word word = new Word();
    // 属性直接引用
		word.setTitle(this.getTitle());
		return word;
	}


	@Override
	public MyPrototype getDeepCloneInstance() {
		// 对象深copy,我们使用对象序列化的方式,注意要实现java.io.Serializable 接口
		try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            MyPrototype copy = (MyPrototype)ois.readObject();
            bos.flush();
            bos.close();
            ois.close();
            return copy;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
	}

	public static void main(String[] args)
	{
		Word word = new Word();
		word.setTitle(new Title());

		Word shadowClone = (Word) word.getShallowCloneInstance();
		Word deepClone = (Word) word.getDeepCloneInstance();

		LogHelper.log("src obj = " + word.getTitle().hashCode());
		LogHelper.log("shadowClone obj = " + shadowClone.getTitle().hashCode());
		LogHelper.log("deepClone obj = " + deepClone.getTitle().hashCode());
	}

}

运行结果为

【www.pangugle.com】-  src obj = 1442407170
【www.pangugle.com】-  shadowClone obj = 1442407170
【www.pangugle.com】-  deepClone obj = 990368553