今天,我要介绍的设计模式叫做原型模式。所谓原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式(取自:菜鸟教程)。在java中,我们最常用的创建对象的方式就是使用new关键字,而原型模式则提供了另一种创建对象的方式,而用这种方式创建对象的效率要比使用new关键字的效率要高。熟系java虚拟机的人都清楚当我们使用new关键字创建对象时需要非常繁琐的数据准备和访问权限而使用原型模式则可以避免重新构建对象的过程。
在java中使用原型模式我们只需要继承Cloneable接口的clone方法即可。代码示例如下:1.首先创建一个是实体类:
public class Car { private String name; private Date createTime; private Integer speed; private String createFactory; public Car(String name, Date createTime, Integer speed, String createFactory) { super(); this.name = name; this.createTime = createTime; this.speed = speed; this.createFactory = createFactory; System.out.println("通过new创建了一个汽车实例"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Integer getSpeed() { return speed; } public void setSpeed(Integer speed) { this.speed = speed; } public String getCreateFactory() { return createFactory; } public void setCreateFactory(String createFactory) { this.createFactory = createFactory; } }
当我们现在需要十个汽车实例时可以通过new关键字来创建十个汽车的实例:
public class PrototyTest { public static void main(String[] args) { for(int i=1;i<=10;i++){ Car car = new Car("奔驰",new Date(),20,"上海大众"); System.out.println("创建了第"+i+"辆"+car.getName()); } } }
执行结果:
通过new创建了一个汽车实例
创建了第6辆奔驰
通过new创建了一个汽车实例
创建了第7辆奔驰
通过new创建了一个汽车实例
创建了第8辆奔驰
通过new创建了一个汽车实例
创建了第9辆奔驰
通过new创建了一个汽车实例
创建了第10辆奔驰
现在我们让汽车类实现Cloneable接口使用原型模式:
public class Car implements Cloneable{ private String name; private Date createTime; private Integer speed; private String createFactory; public Car(String name, Date createTime, Integer speed, String createFactory) { super(); this.name = name; this.createTime = createTime; this.speed = speed; this.createFactory = createFactory; System.out.println("通过new创建了一个汽车实例"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Integer getSpeed() { return speed; } public void setSpeed(Integer speed) { this.speed = speed; } public String getCreateFactory() { return createFactory; } public void setCreateFactory(String createFactory) { this.createFactory = createFactory; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public static void main(String[] args) throws CloneNotSupportedException { Car car = new Car("奔驰",new Date(),20,"上海大众"); System.out.println("创建了第1辆"+car.getName()); for(int i=2;i<=10;i++){ Car carclone1 = (Car)car.clone(); System.out.println("创建了第"+i+"辆"+carclone1.getName()); } } 执行结果:通过new创建了一个汽车实例 创建了第1辆奔驰 创建了第2辆奔驰 创建了第3辆奔驰 创建了第4辆奔驰 创建了第5辆奔驰 创建了第6辆奔驰 创建了第7辆奔驰 创建了第8辆奔驰 创建了第9辆奔驰 创建了第10辆奔驰
当使用原型模式时类的构造方法只执行了一次,提高了效率。这里,我们需要强调一下深克隆和浅克隆的问题。在java中存在两种数据类型,一种是基本数据类型,一种是引用数据类型。其中基本数据类型存储在栈中,引用数据存放在堆中而在栈中存放的是引用数据类型的引用也就是引用数据在堆中的内存地址。浅复制仅仅复制的是引用数据类型的引用,所以当修改克隆对象的引用数据类型的值时会影响原对象。深复制复制了引用数据类型的内存,所以修改克隆对象的引用数据类型的值时不会影响原对象。java中的原型模式属于深克隆。