原型模式

对象创建型模式

模式动机

面向对象系统中,通过原型模式来复制一个对象自身,从而克隆出多个与原型对象一模一样的对象

软件系统中有的对象创建过程很复杂,但有时有需要频繁地创建,这就引入了原型模式。原型模式通过给出一个原型对象来指明所需要创建的对象类型,然后用复制这个原型对象的方法创建更多同类型的对象。

工作原理

原型模式用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象,具体实现上:将一个原型对象传给要发动创建的对象,该对象通过请求原型对象拷贝自己来实现创建过程。原型模式允许一个对象再创建另一个可定制的对象,但无需知道创建的细节。

原型模式包含如下角色:

  • 抽象原型类Prototype
  • 具体原型类ConcretePrototype
  • 客户类Client

应用

原型模式在Java中的实现很简单,比如被所有对象继承的java.lang.Object类就算一个抽象原型类,它提供了一个clone()方法,将对象复制一份。因此可以直接使用Object提供的方法来实现对象的克隆。

需要注意的是,能实现克隆的Java类必须实现一个标识接口Cloneable,表示该类支持克隆操作。

public class PrototypeDemo implements Cloneable {
// ...
public Object clone() {
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("Not support cloneable");
}
return object;
}
// ...
}

在用原型模式对对象进行克隆时,注意两种克隆方式:浅克隆和深克隆

一般而言,clone方法应该满足:

  1. x.clone() != x
  2. x.clone().getClass() == x.getClass()
  3. x.clone().equals(x)

实例:邮件复制(浅克隆)

由于邮件对象包含的内容较多(如发送者、接收者、标题、内容、日期、附件等),某系统中现需要提供一个邮件复制功能,对于已经创建好的邮件对象,可以通过复制的方式创建一个新的邮件对象,如果需要改变某部分内容,无须修改原始的邮件对象,只需要修改复制后得到的邮件对象即可。使用浅克隆进行设计,即复制邮件(Email)时不复制附件(Attachment)。

优点

  1. 当创建对象的实例比较复杂时,原型模式可以简化对象的创建过程,通过已有的实例直接拷贝创建来提高创建效率
  2. 可以通过深克隆保存对象状态

缺点

  1. 每一个原型类都需要分配一个clone方法,而当对已有类进行改造或扩展时,往往不得不修改clone方法,这违背了开闭原则
  2. 深克隆的实现一般较为复杂

适用场合

  1. 创建新对象成本较大。一样的对象可以直接通过拷贝获得而不需要再从头创建,相似对象也可以先拷贝再稍作修改
  2. 系统要保存对象的状态,通过深克隆来实现
  3. 需要避免使用分层次的工厂类来创建分层次的对象,通过拷贝获得新实例可能比使用构造函数创建新实例更加方便时

很多软件提供的ctrl-c和ctrl-v操作就是原型模式的应用。

(•‿•)