在开发一个模块化的应用程序时,我想在每个模块中注入一些助手类。这应该是自动化的。请注意,我的助手是有状态的,所以我不能仅仅使它们是静态的,并在需要的地方包括它们。
我可以使用字符串键将所有帮助程序存储在映射中,并将其提供给所有模块继承的抽象基类。
std::unordered_map<std::string, void*> helpers;
RendererModule renderer = new RendererModule(helpers); // argument is passed to
// base class constructor然后在一个模块中,我可以访问这样的助手。
std::string file = (FileHelper*)helpers["file"]->Read("C:/file.txt");但相反,我想找这样的帮手。
std::string file = File->Read("C:/file.txt");为此,目前我分别为模块基类中的所有助手定义成员,并为每个特定模块设置它们。
FileHelper file = new FileHelper(); // some helper instances are passed to
// multiple modules, while others are
// newly created for each one
RendererModule renderer = new RendererModule();
renderer->File = file;是否有一种方法可以使其自动化,以便在向应用程序中添加新的助手时不必更改模块代码,同时保留第二种语法?我不太熟悉C宏,所以我不知道它们是否能够做到这一点。
发布于 2013-08-17 22:16:04
我想我明白你的困境是什么,但我没有很好的解决办法。然而,由于没有其他答案,我将贡献我的两分钱。
我使用了几种策略的结合来帮助我解决这些问题:
struct (或简单class),并将该结构传递给模块或子系统的构造函数。例如:
struct { // i有时称其为“环境”等。FileHelper * file;LogHelper * log;MemoryHelper * mem;StatsHelper * stats;};
注意:这不是一个特别好或安全的解决方案,但它并不比管理不同的指针更糟糕,而且它很简单。所有这些都假设帮助者不依赖模块(也就是说,他们对依赖级别的抽象程度较低,对模块一无所知)。如果有些帮助程序更接近模块,也就是说,如果您开始想要将模块上的依赖注入到彼此之间,那么上述策略确实会崩溃。
在这些情况下(显然经常发生),我发现集中的ModuleManager单例(可能是全局对象)是最好的。您将显式地将您的模块注册到它中,以及显式的初始化顺序,并且它将构造所有模块。模块可以通过名称(类似于模块指针的字符串映射)请求此ModuleManager对其他模块的引用,但是它们只这样做一次,并以他们想要的任何方式在内部存储指针,以方便和快速的访问。
但是,为了防止混乱的生命周期和销毁顺序问题,每当模块被构造或销毁时,ModuleManager都会通过回调通知所有其他模块,因此它们有机会更新它们的内部指针,以避免出现悬空指针和其他问题。
就这样。顺便说一下,您可能希望研究与“服务定位器”模式相关的文章和实现。
https://stackoverflow.com/questions/18289576
复制相似问题