1.定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2.类图
3.代码示例
1 package com.zhaoyangwoo.prototype; 2 3 /** 4 * Created by john on 16/5/8. 5 */ 6 public class Prototype { 7 public static void main(String[] args){ 8 Product p1= new Product(); 9 p1.setName("nihao"); 10 p1.setAge(2); 11 Product p2 = p1.clone(); 12 System.out.println(p2.getName()); 13 } 14 } 15 16 17 class Product implements Cloneable{ 18 String name; 19 20 Integer age; 21 22 public Product() { 23 System.out.println("调用构造方法"); 24 } 25 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public Integer getAge() { 36 return age; 37 } 38 39 public void setAge(Integer age) { 40 this.age = age; 41 } 42 43 @Override 44 public Product clone() { 45 try { 46 return (Product)super.clone(); 47 } catch (CloneNotSupportedException e) { 48 e.printStackTrace(); 49 } 50 return null; 51 } 52 }
4.应用场景举例
- 一个对象被多个对象使用并且需要修改
- 类型需要多个对象但是对象的初始化消耗巨大
5.JDK源码中的模式实现
在jdk源码中,凡事实现了Cloneable接口的类均使用了此模式。例如我们经常说的Calendar类
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
6.思考
- 原型模式和构造函数
java的原型模式已经在语言中实现。只需要实现Cloneable接口,该接口没有任何实现,只是一个标志。如果没有该接口但是却重写了clone方法,使用时会报异常。
另外java中的原型是直接二进制拷贝,性能客观,这也就能说明复制出来的实体是没有执行构造函数。
- 深复制和浅复制
二进制流的拷贝是浅复制,对于基础类型当然生成新的备份,但是对于引用类型,新老实体对应的都是同一个引用地址。所有如果实体类有引用类型的字段,那么请在
clone方法中重新为引用类型的字段分配空间赋值。