比较在Dart中创建单例的方法

Sur*_*gch 10 singleton dart

我读了这些帖子:

我在理解以下创建单例的方式之间的区别时遇到了一些麻烦:

1.工厂构造函数

class SingletonOne {

  SingletonOne._privateConstructor();

  static final SingletonOne _instance = SingletonOne._privateConstructor();

  factory SingletonOne(){
    return _instance;
  }

}
Run Code Online (Sandbox Code Playgroud)

2.带有吸气剂的静态场

class SingletonTwo {

  SingletonTwo._privateConstructor();

  static final SingletonTwo _instance = SingletonTwo._privateConstructor();

  static SingletonTwo get instance { return _instance;}

}
Run Code Online (Sandbox Code Playgroud)

3.静态场

class SingletonThree {

  SingletonThree._privateConstructor();

  static final SingletonThree instance = SingletonThree._privateConstructor();

}
Run Code Online (Sandbox Code Playgroud)

这些实例化如下:

SingletonOne one = SingletonOne();
SingletonTwo two = SingletonTwo.instance;
SingletonThree three = SingletonThree.instance;
Run Code Online (Sandbox Code Playgroud)

问题

GünterZöchbauer说这个问题

无需使用工厂构造函数。当new不是可选的时,工厂构造函数很方便,因为它new MyClass()适用于每次构造函数都返回一个新实例或该类返回一个缓存实例的类。知道实际创建对象的方式和时间不是呼叫者的责任。

我不明白new现在可选是如何使工厂构造函数现在不必要。在您无法做类似SingletonTwoSingletonThree以上的事情之前?

GünterZöchbauer也说

您还可以更改static final DbHelper _db = new DbHelper._constr();static final DbHelper singleton = new DbHelper._constr();并删除单吸我在我的答案建议。这取决于您的用例。如果您需要其他配置值来创建实例,则可能无法使用字段初始化程序。在您的示例中就足够了。

上面的每个单例模式(SingletonOne,SingletonTwo和SingletonThree)的用例是什么?看看每个例子都是有帮助的。如果你想隐藏的事实类是单(如描述不会工厂模式是有用的在这里)?

Sur*_*gch 18

正如Günter Zöchbauer 在评论中所述,您列出的创建单例的三种方式中的每一种都是相同的。根据您的个人喜好选择一个。

我将添加一些额外的注释:

  • SingletonOne实例化时看起来像任何其他类。因此,如果您想隐藏它是单例的事实(并保留将来使其不是单例的选项),则可以使用此方法。您还可以在构造函数中传入参数。
  • SingletonTwo 将允许您在返回实例之前做其他工作。
  • SingletonThree 是最短的,在我的书中,简洁的代码是可取的,所有其他条件都相同。


Jan*_*sen 5

由于 Dart 允许根级变量,因此可以得到一个完美的、延迟加载的 Singleton:

final store = _Store();

class _Store {
//
}
Run Code Online (Sandbox Code Playgroud)

局限性

与其他三个示例一样,如果您需要异步构造,则这将不起作用。此外,与 SingletonTwo 和 SingletonThree 一样,您不能从调用范围传递任何参数。

对于需要异步构造和参数的单例,我会使用这样的东西:

class StoreService {
  static StoreService? _instance;

  StoreService._() {}

  static Future<StoreService> instance() async {
    // we can await things here
    
    if (_instance == null) {
      _instance = StoreService._();
    }

    return _instance!;
  }
}
Run Code Online (Sandbox Code Playgroud)