Prototype Pattern

原型模式(Prototype pattern),使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建对象。这个定义是从 GoF 中抄来的,不太好懂,但是如果对 JavaScript 的原型继承机制有了解,就很好懂了,这个机制用的模式正是这里的说的原型模式。简单说,就是通过复制一个对象来创建另一个对象,被复制的就是所谓的原型对象。这个模式本身也就是对对象复制的一个提炼性描述。

在有类(class)的语言中去理解这个模式就比较绕,因为有其他方式的干扰。如在 Java 中,要创建一个对象,可以直接 new 一个,也可以去复制一个同类型的对象。后者就是对本文所谓的原型模式的使用。而在 JavaScript 中,要创建一个对象,只能去复制原型对象,只能用原型模式。

复制分为浅复制(shadow clone, 或浅克隆)和深复制(deep clone, 或深克隆)

  • 浅复制。被复制的对象和原型对象的所有变量相同,变量是对象引用的,仍然指向原先引用的对象。即浅复制只复制所考虑的对象,但不复制它所引用的对象。
  • 深复制。被复制的对象和原型对象的所有变量相同,变量是对象引用的,将把引用的对象也复制了,然后指向复制后的对象。即深复制不但复制了自己,且把它引用的其他对象也复制一遍。

图示如下:

shadow and deep clone

A 对象持有一个 B 对象的引用,可以明显看到深浅复制的区别,浅复制中 B 保持原样,而深复制中,B也复制了一份。

在 Java 中,原型对象的类需要实现 Cloneable 接口。java.lang.Object 有 clone() 方法用于复制对象。深复制的实现涉及对象流读写,具体参考文末的参考链接。

其他

原型模式这东西在 Java 中的体现很一般,JavaScript使用原型继承,不知 Lua 如何。

参考

Java 设计模式之原型模式 http://blog.sina.com.cn/s/blog_563742da0100bkep.html