比较在 Dart 中创建单例的方法
Comparing ways to create singletons in Dart
我阅读了这些帖子:
- How do you build a Singleton in Dart?
- Object Structures in Dart
我有点难以理解以下创建单例的方法之间的区别:
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;
问题
about :
There is no need to use the factory constructor. The factory
constructor was convenient when new was not yet optional because then
it new MyClass()
worked for classes where the constructor returned a
new instance every time or where the class returned a cached instance.
It was not the callers responsibility to know how and when the object
was actually created.
我不明白 new
现在是可选的,为什么现在不需要工厂构造函数了。在您无法执行上述 SingletonTwo
或 SingletonThree
之类的操作之前?
:
You can also change static final DbHelper _db = new
DbHelper._constr();
to static final DbHelper singleton = new
DbHelper._constr();
and remove the singleton getter I suggested in my
answer. It depends on your use case. You might not be able to use a
field initializer if you need additional config values to create the
instance. In your example it would be sufficient though.
上述每个单例模式(SingletonOne、SingletonTwo 和 SingletonThree)的用例是什么?看到每一个的例子会很有帮助。如果您想隐藏 class 是单例的事实(如 here 所述),工厂模式不是很有用吗?
如,您列出的三种创建单例的方法都是相同的。根据您的个人喜好选择一个。
我要添加一些额外的注释:
SingletonOne
实例化时看起来与任何其他 class 一样。所以如果你想隐藏它是一个单例的事实,你可以使用这个(并保留让它在将来不是单例的选项)。您也可以在构造函数中传入参数。
SingletonTwo
将允许您在返回实例之前做其他工作。
SingletonThree
是最短的,在我的书中,短而干净的代码是可取的,所有其他条件都相同。
由于 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!;
}
}
我阅读了这些帖子:
- How do you build a Singleton in Dart?
- Object Structures in Dart
我有点难以理解以下创建单例的方法之间的区别:
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;
问题
There is no need to use the factory constructor. The factory constructor was convenient when new was not yet optional because then it
new MyClass()
worked for classes where the constructor returned a new instance every time or where the class returned a cached instance. It was not the callers responsibility to know how and when the object was actually created.
我不明白 new
现在是可选的,为什么现在不需要工厂构造函数了。在您无法执行上述 SingletonTwo
或 SingletonThree
之类的操作之前?
You can also change
static final DbHelper _db = new DbHelper._constr();
tostatic final DbHelper singleton = new DbHelper._constr();
and remove the singleton getter I suggested in my answer. It depends on your use case. You might not be able to use a field initializer if you need additional config values to create the instance. In your example it would be sufficient though.
上述每个单例模式(SingletonOne、SingletonTwo 和 SingletonThree)的用例是什么?看到每一个的例子会很有帮助。如果您想隐藏 class 是单例的事实(如 here 所述),工厂模式不是很有用吗?
如
我要添加一些额外的注释:
SingletonOne
实例化时看起来与任何其他 class 一样。所以如果你想隐藏它是一个单例的事实,你可以使用这个(并保留让它在将来不是单例的选项)。您也可以在构造函数中传入参数。SingletonTwo
将允许您在返回实例之前做其他工作。SingletonThree
是最短的,在我的书中,短而干净的代码是可取的,所有其他条件都相同。
由于 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!;
}
}