如果将不同的参数传递给 dart 中的构造函数,如何重新创建单例实例

How to recreate singleton instance if different params are passed to the constructor in 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"})

然后创建一个新实例,在这种情况下销毁旧实例是可以的。我怎样才能在飞镖中实现这一目标?

您似乎复制了一些现有的创建单例的示例,但没有完全理解它的作用和原因。核心部分是:

  1. 单个实例存储在全局或 static 变量中。
  2. class 有一个或多个 public factory 构造函数 return 全局/static 变量,必要时初始化它。
  3. class 的所有其他构造函数都是私有的,以强制消费者通过 factory 构造函数。

因此,如果您希望 factory 构造函数根据其参数替换其单例,您需要:

  1. 让您的 factory 构造函数检查参数是否适合现有实例。如果是,return 现有实例。如果没有(或者没有现有实例),请创建并 return 一个新实例。
  2. 由于您需要检查现有实例是否已初始化,因此使其可为空。 (您也可以将其初始化为非空标记值,例如 Foo._internal(channel: '').
  3. 将参数传递给私有构造函数。
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!;
  }
}

请注意,如果构造函数参数发生变化,此实现将创建一个 new 对象,这不太像单例。根据您想做什么,您可以:

  • Return 一个新对象(可以同时允许多个实例)。
  • Return 现有对象。
  • Return 现有对象,但使用构造函数参数对其进行变异。