定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
创建型
应用场景
- 类型初始化消耗资源较多、new一个对象的过程非常繁琐。
- 循环体产生大量的对象
优点
- 原型模式性能比new一个对象性能高
- 简化创建流程
缺点
- 必须配置多个克隆方法
- 克隆复杂对象,对克隆出的对象复杂操作复杂的改造,容易引发风险(例如:浅克隆)
源码应用的场景
- JDK 的ArrayList
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
* elements themselves are not copied.)
*
* @return a clone of this <tt>ArrayList</tt> instance
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
}
demo
UML
目录结构
CloneDemo
package creational.prototype;
public class CloneDemo {
/**
* 当前类若没有实现Cloneable那么调用Object的clone将会报CloneNotSupportedException。
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
private static final CloneDemo instance = new CloneDemo();
public static CloneDemo getInstance(){
return instance;
}
/**
* 1、若重写了clone方法不调用Object的clone那么就不用考虑CloneNotSupportedException异常。
*
*/
public static class CloneDemoSubClass extends CloneDemo{
private static final CloneDemoSubClass instance = new CloneDemoSubClass();
public static CloneDemoSubClass getInstance(){
return instance;
}
@Override
protected Object clone(){
return instance;
}
}
public static class Demo1 implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/**
* 1、若父类实现了Cloneable接口,子类调用Object的clone方法并不会抛出CloneNotSupportedException异常。
*
*/
public static class CloneSubClass extends Demo1{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}
Test
package creational.prototype;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
public class CloneDemoTest {
class CloneableTest{
@Override
protected CloneableTest clone() {
return new CloneableTest();
}
}
@Test
public void clone2Test(){
CloneableTest cloneableTest = new CloneableTest();
System.out.println(cloneableTest);
CloneableTest clone = cloneableTest.clone();
System.out.println(clone);
}
@Test
public void cloneJdkDemoTest(){
ArrayList<Date> dates = new ArrayList<>();
Date date = new Date();
dates.add(date);
ArrayList<Date> clone = (ArrayList<Date>) dates.clone();
Date date2 = clone.get(0);
System.out.println(date == date2);//true 浅克隆
}
@Test
public void cloneSub2Test() throws CloneNotSupportedException {
CloneDemo.CloneSubClass cloneSubClass = new CloneDemo.CloneSubClass();
System.out.println(cloneSubClass.clone());
}
@Test
public void cloneSubClassTest(){
CloneDemo.CloneDemoSubClass instance = CloneDemo.CloneDemoSubClass.getInstance();
System.out.println(instance);
Object clone = instance.clone();
System.out.println(clone);
}
@Test
public void singletonDamageTest(){
CloneDemo instance = CloneDemo.getInstance();
System.out.println(instance);
// try {
// Object clone = instance.clone();
//
// System.out.println(clone);
//
// } catch (CloneNotSupportedException e) {
// e.printStackTrace();
// }
}
}