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