我对单例模式有不同的看法。一些人主张应不惜一切代价避免使用它,而另一些人则认为在某些情况下它可能是有用的。
我使用单例的一种情况是当我需要一个工厂(假设类型F的对象f)来创建某个类A的对象时。工厂使用一些配置参数创建一次,然后每次使用类型A被实例化。因此,要实例化A的代码的每个部分都获取单例f并创建新实例,例如
F& f = F::instance();
boost::shared_ptr<A> a = f.createA();
所以我的一般情况是
- 出于优化原因(不需要多个工厂对象)或共享公共状态(例如,工厂知道仍可以创建A的实例),我只需要一个类的实例即可
- 我需要一种方法可以在代码的不同位置访问F的此实例f。
我对讨论此模式的好坏不感兴趣,但是假设我想避免使用单例,我还可以使用其他什么模式?
我的想法是(1)从注册表获取工厂对象,或(2)在程序启动期间的某个时候创建工厂,然后将工厂作为参数传递。
在解决方案(1)中,注册表本身是一个单例,因此我刚刚将不使用单例的问题从工厂转移到了注册表。
在情况(2)中,我需要工厂对象来自的一些初始源(对象),因此恐怕我会再次落入另一个单例(提供我的工厂实例的对象)。通过跟踪此单身人士链,我可以将问题简化为一个单身人士(整个应用程序),通过它 可以直接或间接管理所有其他单身人士。
最后一种选择(使用一个初始单例创建所有其他唯一对象并将所有其他单例注入正确的位置)是否可以接受?当有人建议不要使用单例时,这是隐式建议的解决方案,还是其他解决方案,例如在上述示例中?
编辑
由于我认为我的问题的重点已经被某些人误解了,因此这里提供了更多信息。如所解释的,例如这里,词语 单可指示(a)中的一类具有单个实例对象和(b)用于创建和访问这样的对象的设计模式。
为了使事情更清楚,让我们对(a)使用术语唯一对象, 对(b)使用术语单例模式。因此,我知道单例模式和依赖项注入是什么(顺便说一句,最近我一直在大量使用DI从我正在处理的某些代码中删除单例模式的实例)。
我的观点是,除非整个对象图都是从位于main方法堆栈上的单个对象实例化的,否则始终需要通过singleton模式访问一些唯一的对象。
我的问题是,完整的对象图创建和连接是否取决于主要方法(例如,通过一些不使用模式本身的强大DI框架)是唯一的无 单例模式解决方案。