核心思想
- 原型模式(Prototype Pattern)是一种创建型设计模式。它通过复制现有对象来创建新的对象,而不是通过实例化类。原型模式适用于创建成本较高或复杂的对象,或者需要避免暴露类内部复杂结构的场景。核心思想是 “克隆” 。
编辑
结构
1. Prototype(抽象原型类)
- 定义了一个接口,用于生命
clone
方法。 - 该接口是所有具体原型类的父类。
- 可以是抽象类或接口,具体视需求而定。
2. ConcretePrototype(具体原型类)
- 实现
Prototype
接口。 - 提供对象自身的复制功能,通过实现
clone
方法来生成自身的副本。
3. Client(客户端)
- 调用具体原型类的
clone
方法来复制对象,而无需直接依赖具体类的构造函数。
适用场景
- 对象初始化成本高,需要从数据库加载或执行复杂计算。
- 频繁创建类似对象,如游戏中的道具、地图上的元素。
- 需要动态修改类的结构,如需要在运行时扩展对象类型。
优缺点
优点:
- 减少对象创建成本:通过复制已有对象,避免昂贵的对象初始化过程。
- 隐藏复杂性:调用者无需了解类的具体构造过程。
- 动态增加或减少类:通过克隆原型对象,可以方便地扩展新的对象。
- 简化实例创建:对于需要大量类似对象的场景非常高效。
缺点:
- 克隆包含循环引用的复杂对象可能会非常麻烦:浅拷贝无法正确处理循环引用的场景,可能导致错误或无限递归问题。
实现步骤
- 定义一个实现
Cloneable
接口的原型类。 - 在类中重写
clone()
方法,确保对象的复制逻辑。 - 调用原型的
clone()
方法创建新对象。
注意事项
1. 浅拷贝与深拷贝:
- 浅拷贝:只复制对象的基本数据类型,引用类型属性仍指向原始对象。
- 深拷贝:不仅复制基本类型,也复制引用类型的对象,创建一个完全独立的副本。
2. Cloneable
接口:
- 在 Java 中,必须实现
Cloneable
接口并重写clone()
方法,否则会抛出CloneNotSupportedException
。
3. 不适用场景:
- 对于高度依赖构造函数或不支持
clone()
的框架。
示例
编辑
编辑
与其他模式的关系
- 在许多设计工作的初期都会使用工厂方法模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或生成器模式 (更灵活但更加复杂)。
- 抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法。
- 原型可用于保存命令模式的历史记录。
- 大量使用组合模式和装饰模式的设计通常可从对于原型的使用中获益。 你可以通过该模式来复制复杂结构, 而非从零开始重新构造。
- 原型并不基于继承, 因此没有继承的缺点。 另一方面, 原 型需要对被复制对象进行复杂的初始化。 工厂方法基于继承, 但是它不需要初始化步骤。
- 有时候原型可以作为备忘录模式的一个简化版本, 其条件是你需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。
- 抽象工厂、 生成器和原型都可以用单例模式来实现。