使用原型模式动态配置app

时间:2015-01-29 12:01:16

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

我正在阅读GoF书中的原型模式。这是文本片段

  

动态配置应用程序:某些运行时   环境允许您动态地将类加载到应用程序中。该   原型模式是开发这类设施的关键   像C ++这样的语言。

     

想要创建动态加载实例的应用程序   类将无法静态引用其构造函数。   相反,运行时环境会创建每个类的实例   加载时自动注册,并注册原型   经理。然后应用程序可以向原型管理器询问新内容   加载的类,没有的类;或者与程序一起使用

我的上述问题

  1. 作者的意思是“想要创建动态加载类的实例的应用程序将无法静态引用其构造函数”?例如,如果我们使用动态链接库,我仍然可以使用new创建对象,那么作者的意思是什么,我们将无法静态引用构造函数?

  2. 请求举例说明如何使用原型模式动态利用加载类应用程序。

1 个答案:

答案 0 :(得分:1)

我的50美分:

  1. 我认为作者指的是你在符号库中没有类定义的情况,但是你想要实例化对象,并将它们传递给库消费者函数(所以你是内存所有者,共享库是消费者,但您无法访问库中的具体类)
  2. 示例(我会从头顶写一个以强调有用的场景,然后我会写另一个我实际碰到的场景)

    拥有动态库TextEditorWidgets.dll和您的主应用程序,TextEditorWidget公开了一个抽象原型TEWPrototype,以及根据让我们说某个字符串标识符获取某些原型的工厂方法。

    将工厂方法从定义为:

    的dll中暴露出来
    TEWPrototype* TEWPrototype::getPrototypeFor(string identifier)
    {
          TEWPrototype*  result;
          if (identifier == "SomeWidget")
          {
           result = ConcreteSomeWidgetPrototype;
          } else if ...
          return result;
    }
    

    在您的应用程序中,您可以使用以下代码:

    {
      vector<TEWPrototype*> allocatedWidgets;
      ...
      TEWPrototype* SomeWidget = TEWPrototype::getPrototypeFor("SomeWidget").clone();// you are now the memory owner
      allocatedWidgets.push_back(SomeWidget); // keep for deletion
      TextEditorWidgetsHandle->doSomethingWithTheWidget(SomeWidget);// pass the instantiation to the consumer who knows the widget full definition
    }
    

    在上面的示例中,您有以下专业人员作为应用程序开发人员:

    • 您将控制dll分配的内容,时间和方式
    • 您将控制小部件是否在应用程序的生命周期内被删除

    作为dll开发人员的专业人士:

    • 您可以在提供向后功能的同时添加新的小部件
    • 您可以保证没有人会在.dll
    • 之外使用您的内部小部件功能
  3. 实际例子:

    在游戏开发过程中,游戏开发团队创建了新的实体,我们需要一种快速的方法来为设计师提供新的对象,以便他们添加到游戏场景中。我们有自己的内部编辑器,因此我们可以控制设计工具。

    方法是让World Editor加载.dll,然后在编辑器菜单中公开dll中加载了哪些对象。编辑器不知道dll中有哪些类,它只知道它们有draw和setPosition函数(以及其他一些东西)。

    当加载dll时,在编辑器中,对象的名称被添加到对象原型管理器中(基本上我们有一个静态函数getAvailableObjects,在dll加载之后,我们会查询它以获取字符串)。

    当Designer从菜单中选择一个对象(比如说Crate)时,就会创建一个在编辑器中绘制的该对象的新实例,设计师可以移动它。 / p>

    编辑器无法自己实例化对象,因为他对对象的大小和他的构造函数一无所知。然而,我们为每种类型预先实例化的对象,每次艺术家选择创建一个&#34; new&#34;箱。

    预先实例化的对象也用于预览。

    当开发团队发布一组新的实体时,我们只是向设计师提供了新的dll,他们只需要刷新&#34;编辑器BOOM:魔术发生了:菜单中的新对象。

    作为替代方案,抽象工厂可以提供相同的功能。