什么是原型模式
原型模式(prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
UML图
示例性代码
@Override
public Prototype clone() {
Prototype clone=null;
try {
clone = (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
public class ConcretePrototype1 extends Prototype{
public ConcretePrototype1(String id) {
super(id);
}
@Override
public Prototype clone() {
return super.clone();
}
}
public class ConcretePrototype extends Prototype {
public ConcretePrototype(String id) {
super(id);
}
@Override
public Prototype clone() {
return super.clone();
}
}
值得注意的是在java中使用clone方法必须要实现Clonable接口,否则会抛出CloneNotSupportedException。
同时我们应该注意深拷贝和浅拷贝的区别,浅拷贝和深拷贝都会为我们开辟一个空间来存放对象,浅拷贝会复制基本数据类型的数据,对于对象数据类型的数据仅仅复制其指针,这种拷贝clone函数可以帮我们完成。深拷贝则需要我们自己开辟空间来存储对象数据类型。
以下内容来自此网站
原型模式的使用场景
-
如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
- 这一点考量通常出现在代码需要处理第三方代码通过接口传递过来的对象时。 即使不考虑代码耦合的情况, 你的代码也不能依赖这些对象所属的具体类, 因为你不知道它们的具体信息。
- 原型模式为客户端代码提供一个通用接口, 客户端代码可通过这一接口与所有实现了克隆的对象进行交互, 它也使得客户端代码与其所克隆的对象具体类独立开来。
-
如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。 别人创建这些子类的目的可能是为了创建特定类型的对象。
- 在原型模式中, 你可以使用一系列预生成的、 各种类型的对象作为原型。
客户端不必根据需求对子类进行实例化, 只需找到合适的原型并对其进行克隆即可。
- 在原型模式中, 你可以使用一系列预生成的、 各种类型的对象作为原型。
与其他设计模式之间的关系
-
在许多设计工作的初期都会使用工厂方法模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或建造者模式 (更灵活但更加复杂)。
-
抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法。
-
原型可用于保存命令模式的历史记录。
-
大量使用组合模式和装饰模式的设计通常可从对于原型的使用中获益。 你可以通过该模式来复制复杂结构, 而非从零开始重新构造。
-
有时候原型可以作为备忘录模式的一个简化版本, 其条件是你需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。
-
抽象工厂、 建造者和原型都可以用单例模式来实现。