繁体   English   中英

如何避免对GUI后面的数据使用全局?

[英]How do I avoid using a global for the data behind a GUI?

我正在编写一个音频处理独立应用程序。 我有一个AudioManager对象,它包含与引擎有关的事情(例如I / O设备管理,信号处理路由,运行状态)。 我正在编写一个GUI来控制在后台运行的AudioManager 目前,需要向AudioManager发送消息的每个组件都需要指向它的指针。

当深度嵌套的对象需要指向AudioManager的指针时,这开始变得疯狂,因为这意味着我需要将指针传递给不直接关注AudioManager的GUI对象的构造函数(只有一些子组件需要知道)。

我可以让AudioManager成为单例来避免样板,但是来自类的信息流是双向的,所以这可能是一个坏主意。 我也觉得有点可疑将所有东西都包装成一个大班,但它让它更容易传递。 有没有一个共同的模式来避免无意识的指针传递?

下面是一些伪代码,显示一些构造函数突出显示基本类型的问题。 我已经标记了这个C ++ 11,看看它是否提供了任何独特的解决方案。

MainWindow()
{
    am = new AudioManager();
    someWidget = new SomeWidget(am);
}

SomeWidget(AudioManager* am_) //SomeWidget does not really care about am
{
    someSubComponent = new SubThingy(am_);
}

SubThingy(AudioManager* am_) : subThingyLocalAudioManagerPtr(am_)
{
    subThingyLocalAudioManagerPtr->registerSomethingOrOther(this);
}

在您的示例中,“SomeWidget”应该采用其实际依赖性“SomeThingy”,而不是AudioManager。

通常当你看到整个世界引用一个类时,这意味着该类做得太多了。 出于同样的原因,名称“XyzManager”通常表示存在问题。 (类应以它们的作用命名,如果可用的最具体的名称描述它的作用是“管理”,那么它应该是单独的类)

依赖性注射可能有所帮助。 它还有助于清除所有权问题,并且您可以免费获得更好的可测试性,因为它可以轻松地模拟类。

我们的想法是将所有资源分配转移到工厂; 你的类ctors只接受(智能)指针直接依赖它们。

这些方面的东西:

#include <memory>
using namespace std;

class SubThingy;

class AudioManager { 
  public:
    void registerSomethingOrOther(SubThingy* st) { };
};

// None of the ctors do resource allocation
class SubThingy { 
  public:
    SubThingy(AudioManager* am) : subThingyLocalAudioManagerPtr(am)
    {
      subThingyLocalAudioManagerPtr->registerSomethingOrOther(this);
    };
  private:
    // raw pointer, we don't own it 
    AudioManager* subThingyLocalAudioManagerPtr; 
}; 

class SomeWidget { 
  public:
    // only takes DIRECT depencies
    SomeWidget(unique_ptr<SubThingy> st) : someSubComponent(move(st)) { } 
  private:
    // SomeWidget owns someSubComponent
    unique_ptr<SubThingy> someSubComponent;
};

class MainWindow { 
  public:
    // only takes DIRECT depencies
    MainWindow(unique_ptr<SomeWidget> sw) : someWidget(move(sw)) { }
  private:
    // MainWindow owns its widgets
    unique_ptr<SomeWidget> someWidget; 
};

class Factory { // All memory allocations happen in the factory
  public:
    static unique_ptr<MainWindow> createMainWindow(AudioManager* am) 
    {
      unique_ptr<SubThingy> someSubComponent{ new SubThingy(am) };

      unique_ptr<SomeWidget> someWidget{ new SomeWidget(move(someSubComponent)) };

      return unique_ptr<MainWindow>(new MainWindow(move(someWidget))); 
    }
};

int main() {
  // not clear from the example who owns / should own the audio manager
  AudioManager* am = nullptr;

  auto mainWindow{ Factory::createMainWindow(am) };
}

现在,复杂性将出现在您的工厂类中,但至少将混乱局限于一个地方。

如果工厂变得太大,你可以把它分成不同的类; 甚至更好的是, 为不相关的东西建立不同的工厂 :生产小东西的工厂,小工具的另一家工厂等。

我同意比利的看法,因为经理周围是一个班级试图做太多的标志,应该修改设计。 不幸的是,如果上帝对象住在第三方图书馆而你却无法控制它...... :(

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM