【问题标题】:GUI application and singleton/dependency injectionGUI 应用程序和单例/依赖注入
【发布时间】:2010-07-30 19:04:21
【问题描述】:

我正在开发一个使用 wxWidgets 的带有 GUI 的应用程序。我得到了一个用作“模型”的对象:它的数据必须用于绘制 ui 并且 ui 应该修改它。我们称这个类为Model

应用程序的结构如下所示:

一个wxApp-派生对象,它拥有:

  • 一个wxFrame派生的对象,它拥有一个 wxGLCanvas-派生对象。
  • 另一个wxFrame-派生对象。

对于Model 类,

  1. 我可以使用 singleton 会让事情变得非常简单:我 可以使用model.getThatData()model.setThatData() 任何地方。

    但是,当人们 说它是一个全局变量 一件化装。

  2. 我也可以使用依赖 注入(或者是什么 否则):我实例化 ModelwxApp 对象,然后我传递一个 引用实例model in wxFrame 派生类的构造函数, 与wxGLCanvas 相同 构造函数,我存储 引用作为属性 需要的课程。

    但是,这似乎也不是 很好的解决方案。假设 第一个 wxFrame 对象不需要 使用model。我们还是会 必须传递对model 的引用 在其构造函数中能够 将其传递给wxGLCanvas-derived 目的。所以这种设计可能会导致 许多(?)不必要的路过。

  3. ?

你怎么看?这个问题我问了好久……

【问题讨论】:

    标签: c++ dependency-injection singleton wxwidgets


    【解决方案1】:

    但是,这似乎也不是一个很好的解决方案。假设第一个 wxFrame 对象不需要使用模型。尽管如此,我们仍必须在其构造函数中传递对模型的引用,以便能够将其传递给 wxGLCanvas 派生的对象。所以这种设计可能会导致许多(?)不必要的通过。

    与解开隐藏在实现中的类/对象之间的依赖关系(==单例)的噩梦相比,传递指针是小菜一碟。

    #2 是我的做法。目标是能够通过查看类声明来了解类先决条件。理想情况下,如果在上下文中我拥有 c'tor/init 方法所需的一切,我应该能够实例化和使用该对象。这样生命周期也变得清晰:先决条件可能不会在对象被释放之前被释放。

    【讨论】:

      【解决方案2】:

      框架是否依赖于特定的画布类?还是画布对象可以互换?

      如果是后者,那么框架的构造函数应该通过对画布对象的引用来参数化。这样,应用程序将负责实例化模型,使用所述模型创建画布,并将画布传递给框架。框架将不再直接依赖于模型。

      如果框架依赖于特定的画布类(即框架实例化自己的画布,并且知道它想要什么类型的画布)。然后,如果画布的构造函数依赖于模型对象,则通过代理,您的框架也依赖于模型。所以#2是正确的。

      【讨论】:

      • 画布继承自框架,所以我不能反转东西。我刚刚发现了这个有趣的链接:googletesting.blogspot.com/2008/10/…
      • 该链接或多或少是我在第一个建议中试图说的,尽管有一个更具体的例子。我不知道继承与您的问题有什么关系。如前所述,在我看来,应用程序包含对框架的引用,该框架包含对画布的引用。我的第一个建议仍然有效。
      • 哦,是的,抱歉 :) 我发布链接正是因为它正是您所说的。谢谢!
      【解决方案3】:

      把它放到一个简单的MVC模型中。 (回想一下,C 与 M 和 V 交互,而 M 和 V 不交互。)

      您的模型(显然)是 MVC 中的“M”。您的小部件是 MVC 中的“V”。

      看到这里的问题了吗?您试图将“M”赋予“V”;你错过了委派一切的“C”。你的“C”可能是你的wxApp(这取决于你想如何设计东西)。

      换句话说,控制器应该将视图需要的数据从模型提供给视图;视图不应直接从模型中获取自己的数据。

      (因此,在我看来,您的两个提议在 MVC 应用程序中都是糟糕的选择。)

      【讨论】:

      • 是的! wxApp-派生类对象 (c) 似乎是控制器的好主意。 wxApWxWidgets 提供了一个wxGetApp() 函数,它在任何地方都返回对c 的引用,所以这很完美。抱歉,如果以下内容很愚蠢,但我对 MVC 模型不熟悉。所以,我把我的模型 m 作为私有属性放在 C 中。现在,要从视图中获取模型的属性f,我应该做一个像c.getF() 这样的包装方法,它会调用m.getF()(=> 如果我必须访问许多属性,那就太无聊了)或者可以我有一个c.getM() 函数(几乎是公开的,嗯)?
      • @Klaus,“M”和“V”都不应该知道“C”。控制器只需传递 V 和 M 信息并返回信息。控制器控制信息流;这就是它的工作。如果您让 wxApp 成为控制器,您的视图可能不应该查看 wxApp(尤其是不要访问模型数据)。
      • 所以我应该给视图一个f属性并让控制器根据自己的f更新它?当我想从视图中获取信息时,请使用控制器中的getViewVariable()
      • @Klaus,该视图应该具有公共字段/设置器,以获取其正常运行所需的所有信息。控制器将信息传递到该字段/设置器中。该视图还应具有其提供的所有信息的公共字段/获取器。控制器读取此信息。例如,一个文本框可能有一个 getText getter 和 setText setter,它们允许控制器操作小部件并从小部件中获取它需要的信息。
      猜你喜欢
      • 1970-01-01
      • 2010-09-19
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 2017-11-11
      相关资源
      最近更新 更多