1. 什么是原型模式

原型模式一种创建型设计模式,该模式的核心思想是基于现有的对象创建新的对象,而不是从头开始创建。

在原型模式中,通常有一个原型对象,它被用作创建新对象的模板。新对象通过复制原型对象的属性和状态来创建,而无需知道具体的创建细节。

2. 为什么要使用原型模式

如果一个对象的创建过程比较复杂时(比如需要经过一系列的计算和资源消耗),那每次创建该对象都需要消耗资源,而通过原型模式就可以复制现有的一个对象来迅速创建/克隆一个新对象,不必关心具体的创建细节,可以降低对象创建的成本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import copy

class ComplexObject:
def __init__(self, data):
# 耗时的资源型操作
self.data = data

def clone(self):
# 复制
return copy.deepcopy(self)
# 创建原型对象
original_object = ComplexObject(data="large date")
# 创建新对象,直接拷贝原对象
new_object = original_object.clone()

3. 原型模式的基本结构

实现原型模式需要给【原型对象】声明一个克隆方法,执行该方法会创建一个当前类的新对象,并将原始对象中的成员变量复制到新生成的对象中,而不必实例化。并且在这个过程中只需要调用原型对象的克隆方法,而无需知道原型对象的具体类型。

原型模式包含两个重点模块:

  • 抽象原型接口prototype: 声明一个克隆自身的方法clone
  • 具体原型类ConcretePrototype: 实现clone方法,复制当前对象并返回一个新对象。

在客户端代码中,可以声明一个具体原型类的对象,然后调用clone()方法复制原对象生成一个新的对象

4. 原型模式的基本实现

原型模式的实现过程即上面描述模块的实现过程:

  • 创建一个抽象类或接口,声明一个克隆方法clone
  • 实现具体原型类,重写克隆方法
  • 客户端中实例化具体原型类的对象,并调用其克隆方法来创建新的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 1. 定义抽象原型类
public abstract class Prototype implements Cloneable {
public abstract Prototype clone();
}

// 2. 创建具体原型类
public class ConcretePrototype extends Prototype {
private String data;

public ConcretePrototype(String data) {
this.data = data;
}

@Override
public Prototype clone() {
return new ConcretePrototype(this.data);
}

public String getData() {
return data;
}
}

// 3. 客户端代码
public class Client {
public static void main(String[] args) {
// 创建原型对象
Prototype original = new ConcretePrototype("Original Data");

// 克隆原型对象
Prototype clone = original.clone();

// 输出克隆对象的数据
System.out.println("Clone Data: " + ((ConcretePrototype) clone).getData());
}
}

5. 什么时候实现原型模式

相比于直接实例化对象,通过原型模式复制对象可以减少资源消耗,提高性能,尤其在对象的创建过程复杂或对象的创建代价较大的情况下。当需要频繁创建相似对象、并且可以通过克隆避免重复初始化工作的场景时可以考虑使用原型模式,在克隆对象的时候还可以动态地添加或删除原型对象的属性,创造出相似但不完全相同的对象,提高了灵活性。

但是使用原型模式也需要考虑到如果对象的内部状态包含了引用类型的成员变量,那么实现深拷贝就会变得较为复杂,需要考虑引用类型对象的克隆问题。

原型模式在现有的很多语言中都有应用,比如以下几个经典例子。

  • Java 提供了 Object 类的 clone() 方法,可以实现对象的浅拷贝。类需要实现 Cloneable 接口并重写 clone() 方法。
  • 在 .NET 中,ICloneable 接口提供了 Clone 方法,可以用于实现对象的克隆。
  • Spring 框架中的 Bean 的作用域之一是原型作用域(Prototype Scope),在这个作用域下,Spring 框架会为每次请求创建一个新的 Bean 实例,类似于原型模式。

本站由 卡卡龙 使用 Stellar 1.27.0 主题创建

本站访问量 次. 本文阅读量 次.