c++ - 在频繁引用的情况下替代单例

标签 c++ design-patterns singleton anti-patterns

很多时候单例是一件坏事(例如参见 herehere ),我想避免它们。我还没有其他选择的单例的典型用例是当您有多个必须引用某种父/全局对象的对象时。

示例 1:您有一棵树,每个叶对象都必须知道根对象。 (这是糟糕的设计,但仅用于示例)

示例 2:您有一个“全局”配置对象,通常通过 global_config::get_instance()->get_item(name)

进行访问

问题:对于给定的示例 - 除了广泛的依赖项传递和每个实例存储(又名依赖注入(inject))?

最佳答案

单例只能解决一件事:"static initialization order fiasco"其中全局对象以未定义的顺序实例化,因此它们不能相互依赖。

否则,单例只是全局可访问的对象,恰好只存在一次。

所以对于容器来说,就像第一个例子中的树一样,全局实例并不比单例差。此外,配置(示例 2)主要是启动时反序列化的设置容器,因此没有什么可以阻止您将其设为普通的全局实例。

更好的设计是将应用程序的全局变量分组到“应用程序”类中,因此至少可以清楚地看出它们是应用程序范围的对象,并且无论如何都应该在启动时填写配置。

更好的(对于更大的应用程序)是像更大的对象一样从模块中创建应用程序,并将所需的“全局变量”从“应用程序”类传递给它们,以获得更清晰的依赖关系 View 。这些模块还可以包含接收对“全局变量”的引用的更大对象,但是只要它们知道如何访问其模块化全局变量,就不必访问每个对象。

选择更多依赖注入(inject)方法的最后一个论点是,您的对象将更容易进行模块测试,因为您可以更轻松地注入(inject)测试对象,并且所有具有状态的全局变量往往会干扰一系列测试。

关于c++ - 在频繁引用的情况下替代单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30328294/

相关文章:

c++ - 在 C/C++ 中 for 语句参数内的算术运算

c++ - 在 Objective C 中包含模板化 C++

c# - 为什么要使用 builder 模式?

java - Install4j:如何检查 RemoteCallable 是否未提升运行

c# - 在不接触类的情况下添加属性? (不是继承)

python - 单例 python 生成器?或者,pickle 一个 python 生成器?

c++ - 当指定了意外的位置参数时,boost::program_options不报告错误

c++ - std::vector 对于清除或删除 POD 的行为是否不同

java - 优化和重新设计现有应用程序

c# - 应用外观模式的最佳实践