首页 > 解决方案 > 如果将不同的参数传递给 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"})

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

标签: flutterdartsingleton

解决方案


似乎您已经复制了一些现有示例来创建单例,但没有完全理解它在做什么以及为什么。核心部分是:

  1. 单个实例存储在全局或static变量中。
  2. 该类具有一个或多个公共factory构造函数,它们返回该全局/static变量,并在必要时对其进行初始化。
  3. 该类的所有其他构造函数都是私有的,以强制消费者通过factory构造函数。

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

  1. 让您的factory构造函数检查参数是否适用于现有实例。如果是,则返回现有实例。如果没有(或者如果没有现有实例),则创建并返回一个新实例。
  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!;
  }
}

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

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

推荐阅读