flutter - 如果将不同的参数传递给 dart 中的构造函数,如何重新创建单例实例
问题描述
我收集了以下关于使用参数在 dart 中创建单例的理解
class Foo extends ChangeNotifier {
late String channel;
void instanceMemberFunction () {
print('Foo created with channel $channel')
}
static final Foo _instance = Foo._internal();
Foo._internal() {
instanceMemberFunction();
}
factory Foo({
required String channel
}) {
_instance.channel = channel;
return _instance;
}
}
我这样调用实例
Foo({channel: "bar"})
现在我想做一些工作,如果我使用
Foo({channel: "baz"})
然后创建一个新实例,在这种情况下可以销毁旧实例。我怎样才能在飞镖中实现这一点?
解决方案
似乎您已经复制了一些现有示例来创建单例,但没有完全理解它在做什么以及为什么。核心部分是:
- 单个实例存储在全局或
static
变量中。 - 该类具有一个或多个公共
factory
构造函数,它们返回该全局/static
变量,并在必要时对其进行初始化。 - 该类的所有其他构造函数都是私有的,以强制消费者通过
factory
构造函数。
因此,如果您希望您的factory
构造函数根据其参数替换其单例,您需要:
- 让您的
factory
构造函数检查参数是否适用于现有实例。如果是,则返回现有实例。如果没有(或者如果没有现有实例),则创建并返回一个新实例。 - 由于您需要检查现有实例是否已初始化,因此将其设置为可为空。(您也可以将其初始化为非空标记值,例如
Foo._internal(channel: '')
. - 将参数传递给私有构造函数。
class Foo extends ChangeNotifier {
final String channel;
void instanceMemberFunction () {
print('Foo created with channel $channel');
}
static Foo? _instance;
Foo._internal({required this.channel}) {
instanceMemberFunction();
}
factory Foo({required String channel}) {
if (channel != _instance?.channel) {
_instance = Foo._internal(channel: channel);
}
return _instance!;
}
}
请注意,如果构造函数参数发生更改,此实现将创建一个新对象,这不是很像单例。根据您想做什么,您可以:
- 返回一个新对象(可能允许多个同时实例)。
- 返回现有对象。
- 返回现有对象,但使用构造函数参数对其进行变异。
推荐阅读
- mysql - 查找正好包含两个给定孩子的单亲 id
- xamarin - 在 Visual Studio for Mac 中使用 SiriKit “未找到匹配的配置文件”
- python - TypeError:&:'list'和'list'python不支持的操作数类型
- asp.net-core - 数据种子在 linux 服务器的托管项目中失败。ASP.NET 核心 2.1
- three.js - Three.js 从输入文件本地加载 FBX 和 Materials
- ios - Flutter Methode Channels Objective C 发送和使用 UInt8List
- linux - arm 上的 autocert 中缺少字段或方法签名方案
- android - 如何保护 Android 应用程序中的服务器 URL
- sql - 是否可以在不可为空的列上添加可选引用?
- azure - 使用服务主体的 Hyperledger Cello Ansible Azure