目录

原型模式

Prototype

定义

原型模式就是用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

在原型模式中,所发动创建的对象通过请求原型对象来拷贝原型对象自己来实现创建过程,当然所发动创建的对象需要知道原型对象的类型。这里也就是说所发动创建的对象只需要知道原型对象的类型就可以获得更多的原型实例对象,至于这些原型对象时如何创建的根本不需要关心。

讲到原型模式了,我们就不得不区分两个概念:深拷贝、浅拷贝。

  • 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。
  • 深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。

参与者:

  • Prototype:抽象原型类。声明克隆自身的接口。
  • ConcretePrototype:具体原型类。实现克隆的具体操作。
  • Client:客户类。让一个原型克隆自身,从而获得一个新的对象。

实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class Prototype implements Cloneable{
   private String name = null;
   Public Prototype(String name)
   {
       this.name = name;
   }
    public Object clone(){
      Object object = null;
      try {
        object = super.clone();
      } catch (CloneNotSupportedException exception) {
        System.err.println("Not support cloneable");
      }
      return object;
    }
}

测试

1
2
3
4
5
6
public class Client {
    public static void main(String[] args) {
        Prototype a = new Prototype("小李子");
        Prototype b = (Prototype) a.clone();        
    }
}

优缺点

优点

  • 如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
  • 可以使用深克隆保持对象的状态。
  • 原型模式提供了简化的创建结构。

缺点

  • 在实现深克隆的时候可能需要比较复杂的代码。
  • 需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

使用场景

  • 如果创建新对象成本较大,我们可以利用已有的对象进行复制来获得。
  • 如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
  • 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

总结

  • 原型模式向客户隐藏了创建对象的复杂性。客户只需要知道要创建对象的类型,然后通过请求就可以获得和该对象一模一样的新对象,无须知道具体的创建过程。
  • 克隆分为浅克隆和深克隆两种。
  • 虽然可以利用原型模式来获得一个新对象,但有时对象的复制可能会相当的复杂,比如深克隆。