原型模式
原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象
说白了,原型模式核心便是Ctrl+C 、Ctrl + V。也就是克隆(clone)。
使用场景
- 创建一个对象,这个对象过于复杂,可以使用原型模式来进行复制一个对象。
- 需要提供数据对象,同时有需要避免外部对数据对象进行修改。
- 系统要保存对象状态的,而对象的状态改变很小
原型模式的角色
- Client: 使用者。
- Prototype: 接口(或抽象类),声明具备clone能力。
- ConcretePrototype: 具体的原型类。
深拷贝和浅拷贝
- 我们以ArrayList()为例
ArrayList<String> a = new ArrayList();
ArrayList<String> b = a;
浅拷贝,就是一个对象通过赋值的方式直接传递对象在内存中的内存地址。
ArrayList<String> a = new ArrayList();
ArrayList<String> b = a.clone();
//或者
ArrayList<String> c = new ArrayList(a);
深拷贝,使用clone方法,关于ArrayList的clone方法:
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);
}
}
原型模式优缺点
优点 | 1、当创建的对象实例较为复杂的时候,使用原型模式可以简化对象的创建过程2、扩展性好,由于写原型模式的时候使用了抽象原型类,在客户端进行编程的时候可以将具体的原型类通过配置进行读取。3、可以使用深度克隆来保存对象的状态,使用原型模式进行复制。 |
---|---|
缺点 | 1、需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的里面,当对已有的类经行改造时需要修改源代码,违背了开闭原则。2、在实现深克隆的时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用的时候,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现相对麻烦。 |
总结
原型模式的本质,就是克隆,可以在某些场景中提升构建对象的效率,也可以保护性拷贝,可以通过返回一个返回对象的形式,实现只读的限制。