描述
用原型实例指定要创建的对象类型,并通过原型拷贝创建新对象。
原型提供了另一种不同于工厂方法的方式对创建者类与产品类进行解耦。工厂方法是由子类集成工厂类并重载工厂方法返回具体的类,而原型模式则是用组合代替继承。创建者通过一个提供克隆方法创建对象实例的原型对象进行参数化。通过继承原型对象(如下图中的Concrete Prototype1)或者参数化的方式创建不同的对象。参数化能帮助减少系统中类的数量。
此模式允许类动态加载,在运行时实例化。一般新的原型会被添加到一个已存在的包含其他原型的仓库中。这样系统有很强的动态性,我们可以在不存在运行时组装对象。
分析
克隆方法的实现意义重大,并会涉及有关浅拷贝和深拷贝的话题。此外有可能不能在现存的类上增加克隆方法,例如无权访问类的源代码就属于这类情形。
但是使用Scala的implicit转换,可以在已有的类上增加克隆方法。这为使用原型模式开辟了新的方案。但这只能在克隆对象的声明能够通过对应类的公共接口访问的情况下才能使用。
附注,基于原型的语言(例如JavaScript的self)会直接支持该模式。
模块化
深浅拷贝是一个微妙的问题,一个模块提供通用克隆功能是难以想象的。虽然Scala在标准类层次中提供了clone方法,通常也会被重新。
Scala解决方案
下面代码是在一个已存在的类中添加克隆方法。在这个例子中新添加的复制方法位于CloneA类中,叫做copy。在a上调用该复制方法时,编译器会向调用中插入隐式方法def cloneA(a:A):CloneA ,该方法返回一个新的CloneA对象,然后会在该对象上调用克隆方法copy,返回一个a的复制对象。
class A(var state:Int)
class CloneA(a:A){
def copy = new A(a.state)
}
implicit def cloneA(a:A):CloneA = new CloneA(a)
def main(args:Array[String]) = {
def a = new A(2)
println(a.state)
def aCopy=a.copy
println(a.state)
}
小结
借助scala 隐式转换可以在新的上下文中使用该模式。除此外Scala特性没有为此模式提供特别支持。基于原型的语言直接支持此模式。
Scala解决方案可以在新上下文中使用该模式