前言:
原型模式(Prototype Pattern)属于创建型模式,主要用于创建重复的对象,它是创建对象的最佳方式。能大大的提高性能,通常用在系统中需要创建重复对象,而这些对象的初始化过程比较复杂耗时。对系统性能有较高要求的场景。
特点:
- 直接通过内存拷贝对象,大大的提高了对象的创建效率。
- 基于原型能够快速的创建一个对象,而无需知道创建的细节。
- 可以在运行时动态的获取对象的类型以及状态,从而创建一个对象
实现:
需求:出版社出版书籍的过程,大家都知道写一本书是一个非常耗时耗精力的事情,但是呢,只要原创写完了,可以联系出版社进行大量出版的时候那就快了,可以拿原创书籍进行大量的复制,等复制出来以后又可以随便那一本进行复制。而不用在经过那漫长的创作过程。大大的提高了效率
分析实现:
java本身就提供了clone()方法,所以用java语言实现原型模式是很方便的。只需要将需要复制的对象实现Cloneable接口就好了,然后提供一个clone方法,在clone方法中调用super.clone() 就可以得到复制的对象了。注意:虽然每个对象都有clone()方法,但是,如果这个对象没有实现Cloneable接口,编译的时候会抛出一个CloneNotSupportedException异常
原型模式实现:
项目结构图:
这个模式可以很简单的就实现了,所以项目结构也很简单:一个需要被clone的对象,一个测试类就好了。
相关类源码:
需要被重复创建的类:Book(需要实现Cloneable接口)
在这个类中需要自定义public clone方法,方法中调用父类的clone方法进行对象复制。
public class Book implements Cloneable{
//书名
private String name;
//作者
private String author;
Book(){
System.out.println("无参构成函数实例了Book对象!");
}
Book(String name,String author){
this.name = name;
this.author = author;
System.out.println("有参构成函数实例了Book对象!");
}
Book(String name,String author){
this.name = name;
this.author = author;
System.out.println("实例了Book对象!");
}
public Book clone() throws CloneNotSupportedException {
return (Book) super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
测试类:TestMain
这里主要测试一下使用clone方法创建对象的时候,有没有创建出和已实例对象一样的对象。如果clone成功,并且没有打印Book的构造方法中要打印的字符串,然后随便取一个复制对象和源对象进行==比较,应该打印false。就说明使用原型模式clone对象成功了。
public class TestMain {
public static void main(String[] args) throws CloneNotSupportedException {
//创建第一本书
Book book = new Book("java设计模式", "刘伟");
List<Book> bookList = new ArrayList<Book>();
//复制5本
for (int i = 0; i<5; i++){
Book bookCopy = book.clone();
bookList.add(bookCopy);
}
System.out.println("原创Book书名:"+book.getName()+"\t作者:"+book.getAuthor());
for (int i = 0; i < bookList.size(); i++) {
System.out.println("Book"+i+":书名:"+bookList.get(i).getName()+"\t作者:"+bookList.get(i).getAuthor());
}
//随便取本书和原创那本进行比较,打印:false
System.out.println(book==bookList.get(0));
}
}
测试结果:
从结果中可以看出,只有第一本书创建的时候调用了构造方法,而其他clone得到的book都没有调用。
总结:
总结整理一下原型模式的优缺点(来自互联网各位师兄的总结)
优点:
- 原型模式直接利用内存拷贝对象,提高对象的创建性效率。适合用在需要创建大量对象或者类初始化消耗多资源的场景下。
- 原型模式提供了简化的创建结构,工厂方法模式常常需要有一个与产品类等级结构相同的工厂等级结构,而原型模式就不需要这样
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
- 比如需要实现要Cloneable接口(实现cloneable的接口一般是实现浅克隆,深克隆这里先不说了,以后有机会补充)并且还有创建一个clone对象的方法才可以进行对象clone,增加了代码量。并且克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
- 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重签到引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。