原型模式

时间:2012-07-30 10:54:26

标签: c++ design-patterns prototype-pattern

根据维基百科的原型模式是: 原型模式是在软件开发中使用的创建设计模式,当要创建的对象类型由原型实例确定时,该实例被克隆以生成新对象。此模式用于:

  1. 避免客户端应用程序中的对象创建者的子类,如抽象工厂模式那样。

  2. 避免以标准方式创建新对象的固有成本(例如,使用new关键字),但对于给定的应用程序来说,这是非常昂贵的。


  3. 我在C ++中看到了这种模式的某些演示代码,所有这些代码都使用了复制构造函数。 任何人都可以解释第二点如何应用(通常以及在C ++的上下文中),因为我们在克隆函数中使用复制构造函数。如果可以在没有复制构造函数的情况下完成,那么示例代码片段就会很棒。

3 个答案:

答案 0 :(得分:2)

您无需动态分配即可复制。例如,这是一个仅在本地范围内发生的克隆:

Foo prototype;

void local()
{
    Foo x = prototype; // first copy
    x.mutate();
    Foo y = x;         // another copy
}

永远不会使用动态分配。

return new Foo(*this); 确实也是复制,但更重要的是 对象是动态分配的。 是你的文章提到的成本。

答案 1 :(得分:1)

在我用Java编写的游戏中,我遇到了一个非常适合原型模式的有趣情况。你看,我有这个动画对象存储了一个容器翻转的图像,以及跟踪自上一帧渲染后多长时间,其所在框架,动画是否正在运行等的其他数据等。

我发现多个字符使用相同的Animation对象导致了问题。如果两个角色共享动画,则它们会在相互冲突的时间打开并关闭动画。我会让人们站着不动的动画,或者站着动画。动画对象的创建既费时又费时,创建精灵,设置显示的时间,创建图像间隔队列等等。

相反,我将Animation对象设为原型对象。如果动画克隆自身,它与所有其他动画共享原始帧集合,因为它们是不可变的,但构造起来也很昂贵。相反,新对象将共享这个不可变的基础,但是有自己的信息来绘制哪个框架以及何时绘制。

把它想象成一台投影机。当它被克隆时,新投影机可能拥有它自己的信息,如果它正在运行,它是否正在运行,等等,但它可能使用与原始投影机正在使用的相同的胶片。他们之间没有相互绊倒的原因是电影是不可改变的。 (并且创建起来很昂贵)

老实说,以这种方式使用原型是实现flyweight模式的好方法。共享创建成本高昂的对象的对象。如果你“克隆”它们,它们将被实例化为它们的新瞬态,但仍然与它的创建者共享那些昂贵的基础对象。

答案 2 :(得分:-1)

为不使用动态内存的对象调用复制构造函数要比通过new在动态内存中执行任何分配快得多。因为动态内存中的分配是一种系统调用。