原型模式

别名

  • Clone

意图

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

Specify the kinds of objects to create using a prototypical instance, and create
new objects by copying this prototype.

结构

049306316682.png

参与者

Prototype

  • 声明一个克隆自身的接口。

ConcretePrototype

  • 实现一个克隆自身的操作。

Client

  • 让一个原型克隆自身从而创建一个新的对象。

适用性

在以下情况下可以使用 Prototype 模式:

  • 一个系统要独立于它的产品的创建、构成和表示时。

  • 当要实例化的类是在运行时刻指定时,例如:通过动态装载。

  • 为了避免创建一个与产品类层次平行的工厂类层次时。

  • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

缺点

  • 每一个 Prototype 子类都必须实现 Clone
    操作。当内部包括一些不支持拷贝或有循环引用的对象时,实现克隆可能也会很困难。

效果

  • 它对客户隐藏了具体的产品类,因此减少了客户知道的名字的数目。

  • 使客户无需改变即可使用与特定应用相关的类。

  • 运行时刻增加和删除产品。

  • 改变值以指定新对象。

  • 改变结构以指定新对象。

  • 减少子类的构造。

  • 用类动态配置应用。

相关模式

  • Abstract Factory 可以用
    Prototype 来实现。

  • Composite 和
    Decorator 模式的设计也可以从
    Prototype 获益。

命名约定

使用命名约定是一个好习惯,例如,总是声明那些实现克隆的操作为 Clone()。

Implementation

1
2
3
public abstract class Prototype {
abstract Prototype myClone();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ConcretePrototype extends Prototype {

private String filed;

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

@Override
Prototype myClone() {
return new ConcretePrototype(filed);
}

@Override
public String toString() {
return filed;
}
}
1
2
3
4
5
6
7
public class Client {
public static void main(String[] args) {
Prototype prototype = new ConcretePrototype("abc");
Prototype clone = prototype.myClone();
System.out.println(clone.toString());
}
}
1
abc

JDK