一、简介
1.定义
一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例,其中被复制的实例就是我们所称的原型。
原型模式的本质:克隆生成对象。
2.什么时候用?
- 使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
- 使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。
二、原型模式在Java中的应用
1.Cloneable接口
Java中,我们可以通过实现java.lang.Cloneable接口来实现原型模式。
需要注意的是这里是直接在内存中复制收据,不会调用类的构造方法,而且会破坏单例模式。
2.浅度克隆:
仅仅是值克隆,即原型对象和克隆对象属性的值一样,对于引用类型指向的是同一个对象
3.深度克隆:
值克隆+引用对象的克隆,即引用对象也会进行克隆获得新的对象给对应属性。
4.简单实例
注意:Book中的clone()方法“rtn.setAuthor((Author) this.getAuthor().clone());”如果没有这句,仅仅是浅度克隆,原型对象和克隆对象引用的是同一个Author对象,而这句就是为了实现深度克隆。
public class Author implements Cloneable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public class Book implements Cloneable { private String name; private int pageNum; private Author author; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } @Override public Object clone() throws CloneNotSupportedException { Book rtn = (Book) super.clone(); rtn.setAuthor((Author) this.getAuthor().clone()); return rtn; } }
public class PrototypeTest { public static void main(String[] args) throws Exception { Author author = new Author(); author.setName("金庸"); author.setAge(65); Book book = new Book(); book.setName("射雕英雄传"); book.setPageNum(230); book.setAuthor(author); Book newBook = (Book) book.clone(); System.out.println(newBook == book); System.out.println(newBook.getAuthor() == book.getAuthor()); } }