通常,单例模式是通过使用静态方法创建一个类来实现的,该方法如果不存在,则创建该类的新实例。如果实例已存在,则只返回对该对象的引用。为了确保无法以任何其他方式实例化对象,构造函数将变为私有。有没有其他方法可以创建单身人士?
答案 0 :(得分:1)
(如果您的语言支持)
public static readonly MyClass singleton = new MyClass(); // create at class/assembly load/access
public static final MyClass singleton;
static {
singleton = new MyClass();
}
// header
class MyClass {
public:
static MyClass singleton; // value, created before main, or at dll load
static MyClass const * singleton; // const ptr to non-const value, created before main
private:
MyClass();
~MyClass();
MyClass(const Myclass&) = delete; // c++11, remove default implementation
}
// in cpp:
MyClass Myclass::singleton;
MyClass const* MyClass::singleton = new MyClsas;
对于大多数编译器/语言,这可以避免需要线程锁定和初始化/销毁顺序问题的按需创建问题。
然而,我做单例的首选方法是在某处创建一个字段/属性并显式初始化(在main中或通过一些依赖注入框架。这对管理许多单例类型有很大帮助,特别是对于测试。
如果你愿意,你可以另外测试并阻止设置singleton属性设置多次,至少在没有运行测试时。
int main()
{
// Just set it. Use discipline to prevent others
MyClass.singleton = new MyClass();
// Use function, then we can enforce set-only-once, if required
MyClass.setSingleton(new MyClass());
// dependency injection via env-vars! :)
MyClass::setSingleton(ClassFactory::create(getenv("MYCLASS_SINGLETON_TYPE"));
mainLoop();
}
拥有“管理员”或“注册表”或其他任何东西以保存所有全局对象通常很方便。然后该类可以负责创建/设置所需的所有大型单例对象。
这样,您用作单身人士的班级不需要关心单身人士。在测试或“重置”样式场景时非常有用。
它还有助于将所有这些“大”对象集中在某处,以便可以在一个地方找到并管理全局状态,而不是在整个应用程序中找到5-25个不同的类。
答案 1 :(得分:0)
您可以在方法中同步称为双重检查锁定的最常见模式。
http://en.wikipedia.org/wiki/Double-checked_locking
这里有一些关于双重检查锁定的代码示例。:
http://javarevisited.blogspot.co.il/2014/05/double-checked-locking-on-singleton-in-java.html
修改强>
使用double检查的主要好处是你可以使用多个线程运行该函数,而只有在创建新对象的 critical 部分是在锁定下完成的。