创建型模式——原型模式

1、什么是原型模式

原型模式就是将一个已有的实例对象,将其复制出一个一模一样的实例对象出来,也就是克隆,原型模式算是设计模式中最简单的一个。它的核心就是类图中的Prototype类,实现原型模式非常简单,只需要两步,第一是实现Cloneable这一个接口,这个接口与Serializable(序列化)一样,是一个标识性接口,接口内部没有任何的内容,这个接口的作用就是通知jvm,可以在实现了这个接口的类上使用clone方法,复制一个一样的实例,如果一个接口没有实现Cloneable这个接口,直接去调用Object类中的clone()方法,就是抛出CloneNotSupportedException的异常。第二就是在类重写Object类中的clone方法,这个方法的方法体一般就只有一条语句:super.clone(),就是将克隆的工作让父类去完成,一般不会直接克隆一个实现Cloenable接口的类,而间接去使用它的子类,去完成克隆。Object类中的clone方法的原型是protected native Object clone() throws CloneNotSupportedException;也就是调用调用本地的c/c++代码去实现克隆。


2、原型模式的java实现

2.1Prototype类

public class Prototype implements Cloneable {
	public Prototype() {
		System.out.println("Prototype 构造");
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

}

2.2ConcetePrototype类

public class ConcetePrototype extends Prototype {
    public ConcetePrototype() {
    	System.out.println("ConcetePrototype 构造");
    }
    
    public void show(){
    	System.out.println(this);
    }

}

2.3Client类

public class client {
	public static void main(String[] args) throws CloneNotSupportedException {
		ConcetePrototype cp = new ConcetePrototype();
		cp.show();
		for (int i = 0; i < 10; i++) {
			ConcetePrototype clone1 = (ConcetePrototype) cp.clone();
			clone1.show();
		}
	}

}

在本地控制台打印的结果为:

Prototype 构造
ConcetePrototype 构造
ConcetePrototype@152b6651
ConcetePrototype@544a5ab2
ConcetePrototype@5d888759
ConcetePrototype@2e6e1408
ConcetePrototype@3ce53108
ConcetePrototype@6af62373
ConcetePrototype@459189e1
ConcetePrototype@55f33675
ConcetePrototype@527c6768
ConcetePrototype@65690726
ConcetePrototype@525483cd

这说明在进行克隆的过程中是不会去调用被克隆类的构造函数的,最开始的两个构造是一开台创建一个ConcetePrototyoe而调用的。克隆不是去创建(new)一个新对象,而是交由jvm调用本地方法,直接使用类的字节码去复制出一个新的对象。


3、原型模式的应用场景

使用原型模式去克隆一个对象比使用new关键字去创建一个对象性能要高,因为克隆是调用本地c/c++代码,直接对内存的二进制数据进行操作,所以当创建的实例比较大时,使用克隆比new要好,当要反复的创建同一种类对象时,就可以考虑采用原型模式以提高程序的性能。

4、深拷贝与浅拷贝

在java体系中,调用clone()方法是不会c克隆List、Set等数组或容器对象,只会去克隆8种基本类型(byte,char,short,int,float,double,long,boolean)和一个String类型。在Prototype类中新增一个LinkedList对象,克隆了3个对象,打印这个3个对象中的List的hashcode值,发现是一个样,但3个对象的地址是不一样的,说明,这个默认的浅拷贝,类内部的引用对象是不会被拷贝的,如果将这些引用对象也进行拷贝,这就是深拷贝。LinkedList这个类本身也实现了Cloneable接口,所以在对整个类克隆时,对重写的clone()方法做如下改动

import java.util.LinkedList;

public class Prototype implements Cloneable {
	protected LinkedList list = new LinkedList();

	public Prototype() {
		System.out.println("Prototype 构造");
	}

	@Override
	protected Prototype clone() throws CloneNotSupportedException {
		Prototype prototype=(Prototype) super.clone();
		prototype.list=(LinkedList) list.clone();
		return prototype;
	}

}

5、原型模式注意事项

5.1克隆不会去调用构造函数

5.2克隆有深拷贝与浅拷贝之分

5.3原型模式与单例模式是冲突的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值