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

时间:2019-01-06 01:46:41

标签: dart singleton

我读了这些帖子:

我很难理解以下创建单例的方式之间的区别:

1。工厂构造函数

class SingletonOne {

  SingletonOne._privateConstructor();

  static final SingletonOne _instance = SingletonOne._privateConstructor();

  factory SingletonOne(){
    return _instance;
  }

}

2。带有getter的静态字段

class SingletonTwo {

  SingletonTwo._privateConstructor();

  static final SingletonTwo _instance = SingletonTwo._privateConstructor();

  static SingletonTwo get instance { return _instance;}

}

3。静态字段

class SingletonThree {

  SingletonThree._privateConstructor();

  static final SingletonThree instance = SingletonThree._privateConstructor();

}

这些实例化如下:

SingletonOne one = SingletonOne();
SingletonTwo two = SingletonTwo.instance;
SingletonThree three = SingletonThree.instance;

问题

Günter Zöchbauer said关于this question

  

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

我不知道现在new是可选的使工厂构造函数现在不必要了。在您无法执行上述SingletonTwoSingletonThree之类的事情之前?

Günter Zöchbauer also said

  

您也可以将static final DbHelper _db = new DbHelper._constr();更改为static final DbHelper singleton = new DbHelper._constr();并删除我在我的建议中提出的单例消气剂   回答。这取决于您的用例。您可能无法使用   字段初始值设定项,如果您需要其他配置值来创建   实例。在您的示例中就足够了。

上述每个单例模式(SingletonOne,SingletonTwo和SingletonThree)的用例是什么?看看每个例子都是有帮助的。如果您想隐藏该类是单例的事实(如here所述),那么工厂模式是否有用?

2 个答案:

答案 0 :(得分:1)

由于 Dart 允许根级变量,因此可以拥有一个非常好的延迟加载单例:

final store = _Store();

class _Store {
//
}

限制

与您的其他三个示例一样,如果您需要异步构造,这将不起作用。此外,像 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!;
  }
}

答案 1 :(得分:0)

Günter Zöchbauer stated in the comments一样,您列出的创建单例的三种方式都是相同的。根据个人喜好选择一个。

我要添加一些其他注释:

  • SingletonOne实例化时与任何其他类相似。因此,如果您想隐藏它是单身的事实(并保留选择使其将来不再是单身)的事实,可以使用此选项。您还可以在构造函数中传递参数。
  • SingletonTwo将允许您在返回实例之前执行其他工作。
  • SingletonThree是最短的,在所有其他条件相同的情况下,我的书中希望使用简短的简洁代码。

我将其作为临时答案提交,希望获得反馈。也欢迎其他更完整/更好的答案。