【问题标题】:configuring app dynamically using prototype pattern使用原型模式动态配置应用程序
【发布时间】:2015-01-29 12:01:15
【问题描述】:

我正在阅读 GoF 中有关原型模式的书籍。这是文本sn-p

使用类动态配置应用程序:一些运行时 环境允许您将类动态加载到应用程序中。这 原型模式是在一个 像 C++ 这样的语言。

想要创建动态加载的实例的应用程序 类将无法静态引用其构造函数。 相反,运行时环境会为每个类创建一个实例 加载时自动注册,并使用原型注册 经理。然后应用程序可以向原型管理器请求新的 加载的类,不是最初由程序引入的类

我在上面的问题

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

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

【问题讨论】:

  • 只有在编译时知道类名时才能使用构造函数。该模式的前提之一是您不知道这些名称。

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


【解决方案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 之外使用您的内部小部件功能

实际例子:

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

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

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

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

编辑器不能自己实例化对象,因为他对对象的大小和构造函数一无所知。然而,我们为每种类型预先实例化了对象,每次艺术家选择创建“新”Crate 时,这些对象都会被克隆。

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

当开发团队发布一组新实体时,我们只是向设计师提供了新的 dll,他们只需要“刷新”编辑器一个 BOOM:神奇发生了:菜单中的新对象。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 2012-07-28
    • 2012-08-13
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    相关资源
    最近更新 更多