简介
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。
浅拷贝与深拷贝
在实现Cloneable接口时,进行拷贝对象,效率比构造函数要高,也避免了构造传参的麻烦。
拷贝对象分为浅拷贝和深拷贝,默认的Object.clone()是浅拷贝。浅拷贝只能复制基本数据类型和基本数据类型的包装类,以及特殊的String类。如果是复杂的引用类型,浅拷贝会直接拷贝引用,如果原始对象修改了引用对象内部属性的值,所有拷贝的对象的值会跟着变,这会引发安全问题。
也就是说,当对象的属性中包含复杂的对象时,要使用深拷贝,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。
简单的深拷贝实现是,在对象的每一层中都调用clone方法,即可实现深拷贝,即每层对象浅拷贝 = 深拷贝。如果对象层次比较多,调用clone会很复杂,这时可以使用序列化,再反序列化回来的方式进行深拷贝,另外通过序列化为json字符串,然后从json字符串转回来也是比较常用的方式。
应用实例
克隆羊,通过clone方法进行复制多个对象,这里使用浅拷贝就可以。
package com.mori.design.pattern.prototype;/*** 羊* @author mori*/public class Sheep implements Cloneable{private String name;private Integer age;private String color;public Sheep(String name, Integer age, String color) {super();this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}/*** 克隆该实例,使用默认的clone方法来完成*/@Overridepublic Sheep clone() {Sheep sheep = null;try {sheep = (Sheep)super.clone();} catch (Exception e) {e.printStackTrace();}return sheep;}@Overridepublic String toString() {return "Sheep [name=" + name + ", age=" + age + ", color=" + color + "]";}}
测试代码如下
public void testSheep(){Sheep sheep = new Sheep("小样", 12, "白色");Sheep sheep2 = sheep.clone();Sheep sheep3 = sheep.clone();Sheep sheep4 = sheep.clone();System.out.println(sheep);System.out.println(sheep2);System.out.println(sheep3);System.out.println(sheep4);}
控制台输出:
Sheep [name=小样, age=12, color=白色]Sheep [name=小样, age=12, color=白色]Sheep [name=小样, age=12, color=白色]Sheep [name=小样, age=12, color=白色]
