设计模式之原型模式

设计模式之原型模式

什么是原型模式?

原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。

原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。因此它提供了一种对象创建机制。

当创建对象的事务非常昂贵并且需要大量时间和资源并且您已经存在类似的对象时,可以使用原型设计模式。

原型模式类图

描述原型设计模式的UML类图。

原型模式示例

用一个例子很容易理解原型设计模式。 假设我们有一个从数据库加载数据的对象。 现在,我们需要在程序中多次修改此数据,因此使用new关键字创建Object并再次从数据库中加载所有数据不是一个好主意。

更好的方法是将现有对象克隆到新对象中,然后进行数据操作。

原型设计模式要求您要复制的对象应提供复制功能。 不应由其他任何类完成。 但是,使用对象属性的浅拷贝还是深拷贝取决于要求及其设计决策。

这是一个示例程序,显示了Java中的原型设计模式示例。

Employees.java

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
37
import java.util.ArrayList;
import java.util.List;

/**
* 员工类
*
* @author Mr.zxb
* @date 2020-09-15 16:50
*/
public class Employees implements Cloneable {
private List<String> empList;

public Employees() {
this.empList = new ArrayList<>();
}

public Employees(List<String> empList) {
this.empList = empList;
}

public void loadDate() {
// 从数据库中读取所有员工并放入列表
empList.add("Lisa");
empList.add("David");
empList.add("Allen");
empList.add("Helen");
}

public List<String> getEmpList() {
return empList;
}

@Override
protected Object clone() throws CloneNotSupportedException {
return new Employees(new ArrayList<>(this.getEmpList()));
}
}

注意:覆盖clone()方法以提供雇员列表的深拷贝。

测试原型模式

这是原型设计模式示例测试程序,将显示原型模式的好处:

PrototypePatternTest.java

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
/**
* 测试原型模式
*
* @author Mr.zxb
* @date 2020-09-15 16:57
*/
public class PrototypePatternTest {
public static void main(String[] args) throws CloneNotSupportedException {
// 创建 Employees 实例
Employees employees = new Employees();
// 加载数据
employees.loadDate();

// 使用 clone方法来获取 Employees对象
Employees empsNew = (Employees) employees.clone();
Employees empsNew1 = (Employees) employees.clone();
List<String> list = empsNew.getEmpList();
list.add("John");
List<String> list1 = empsNew1.getEmpList();
list1.remove("David");

System.out.println("employees List: "+ employees.getEmpList());
System.out.println("empsNew List: " + list);
System.out.println("empsNew1 List: " + list1);
}
}

以上原型设计模式示例程序的输出为:

1
2
3
employees List: [Lisa, David, Allen, Helen]
empsNew List: [Lisa, David, Allen, Helen, John]
empsNew1 List: [Lisa, Allen, Helen]

如果未提供对象克隆,我们将必须进行数据库调用以每次获取员工列表。 然后进行那些本来会很耗资源和时间的操作。这就是Java中的原型设计模式。

原型模式的优点

  • 向客户隐藏制造新实例的复杂性
  • 提供让客户能够产生未知类型对象的选项
  • 在某些环境下,复制对象比创建对象更有效

原型模式的用途

  • 在一个复杂的类层次中,当系统必须从其中的许多类型创建新对象时,可以考虑原型模式
  • 对象构建成本很高,我们可以将对象的克隆用于将来使用
  • 可以减少构建新对象的昂贵数据库调用
  • 需要在动态加载时在运行时实例化类时
  • 当对象创建复杂且耗时时需要
  • 当需要将对象组成,创建和表示与客户端应用程序分离时