什么是原型模式
原型模式(Prototype Pattern)属于创建型模式,用于创建重复的对象。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。
基本角色
Client:客户端角色。
Prototype:抽象原型角色,抽象类或者接口,用来声明clone方法。
ConcretePrototype:具体的原型类,是客户端角色使用的对象,即被复制的对象。
注意,Prototype通常是不用自己定义的,因为拷贝这个操作十分常用,Java中就提供了Cloneable接口来支持拷贝操作,它就是原型模式中的Prototype。当然,原型模式也未必非得去实现Cloneable接口,也有其他的实现方式。
代码
ConcretePrototype(具体原型类)
//实现Cloneable接口,它是一个标识接口,表示这个对象是可拷贝的,只要重写clone方法就可以实现拷贝。
public class ConcretePrototype implements Cloneable {
private String name;
private int age;
public ConcretePrototype() {
System.out.println("ConcretePrototype构造函数执行");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//clone方法不是在Cloneable接口中定义的(Cloneable接口中没有定义任何方法),而是在Object中定义的。
@Override
protected ConcretePrototype clone() throws CloneNotSupportedException {
ConcretePrototype concretePrototype = null;
try {
concretePrototype = (ConcretePrototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return concretePrototype;
}
}
client(客户端)
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
ConcretePrototype c1 = new ConcretePrototype();
c1.setName("name");
c1.setAge(10);
//拷贝
ConcretePrototype c2 = c1.clone();
System.out.println(c2.getName()); //name
System.out.println(c2.getAge()); //10
c2.setName("nameC2");
c2.setAge(12);
System.out.println(c2.getName()); //nameC2
System.out.println(c2.getAge()); //12
}
}
运行结果:
ConcretePrototype构造函数执行
name
10
nameC2
12
需要注意的是,clone方法并不会执行ConcretePrototype 的构造函数。
原型模式的使用场景
- 如果类的初始化需要耗费较多的资源,那么可以通过原型拷贝避免这些消耗。
- 如果通过new创建对象需要非常繁琐的数据准备或访问权限时,可使用原型模式。
- 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以拷贝多个对象供调用者使用,即保护性拷贝。
原型模式的优点
原型模式是在内存中二进制流的拷贝,要比new一个对象的性能要好,特别是需要产生大量对象时。
原型模式的缺点
直接在内存中拷贝,构造函数不会执行。