依赖注入可能会有所帮助。它还有助于清除所有权问题,并且您可以免费获得更好的可测试性,因为它可以轻松模拟类。
这个想法是将所有资源分配转移到工厂;您的类 ctor 仅采用(智能)指向其直接依赖项的指针。
这些方面的东西:
#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) };
}
现在,复杂性将出现在您的工厂类中,但至少混乱将被限制在一个地方。
如果工厂变得太大,您可以将其拆分为单独的类;甚至更好的是,有不同的工厂来生产不相关的东西:一个生产东西的工厂,另一个生产小部件的工厂,等等。
我同意比利的观点,有一个经理在身边是一个班级试图做太多事情的标志,应该修改设计。不幸的是,如果上帝对象存在于第三方库中并且您无法控制它... :(