【问题标题】:Comparing ways to create singletons in Dart比较在 Dart 中创建单例的方法
【发布时间】:2019-06-01 03:33:14
【问题描述】:

我读过这些帖子:

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

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 所述),工厂模式不是很有用吗?

【问题讨论】:

  • 都是一样的。只使用你最喜欢的。

标签: dart singleton


【解决方案1】:

作为Günter Zöchbauer stated in the comments,您列出的创建单例的三种方式中的每一种都是相同的。使用您的个人喜好选择一个。

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

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

【讨论】:

    【解决方案2】:

    由于 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!;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-19
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 2019-11-22
      • 1970-01-01
      • 2020-04-24
      • 1970-01-01
      相关资源
      最近更新 更多