在 Dart 中,是否可以在单例中传递参数?

问题描述 投票:0回答:6
class Peoples {
  late int id;
  late String name;

  static final Peoples _inst = Peoples._internal();

  Peoples._internal();

  factory Peoples() {
    return _inst;
  }
}

我有这个单例类。这确保了只有一个类的实例被创建。因此,即使有人尝试实例化它,他们也会使用相同的实例。我可以创建和设置值,例如:

  Peoples ps1 = Peoples();
  Peoples ps2 = Peoples();

  ps1.id = 1;
  ps1.name = "First";

  ps2.id = 2;
  ps2.name = "Second";

是否可以实例化并设置如下值:

  Peoples ps1 = Peoples(1, "First");
  Peoples ps2 = Peoples(2, "Second");

所以,现在“ps1”和“ps2”都会有(2,“第二”)。

oop dart flutter singleton
6个回答
56
投票

当然! 您需要将参数传递给工厂方法,然后需要使用引用的实例更新属性。

例如,你有

class Peoples {
  late int id;
  late String name;

  static final Peoples _inst = Peoples._internal();

  Peoples._internal();

  factory Peoples() {
    return _inst;
  }
}

如果您应用我的解决方案,那么您就拥有了

class Peoples {
  late int id;
  late String name;

  static final Peoples _inst = Peoples._internal();

  Peoples._internal();

  factory Peoples({int id, String name}) {
    _inst.id = id
    _inst.name = name
    return _inst;
  }
}

这样你的问题就应该得到解答 有关工厂和参数的更多信息,请访问

https://dart.dev/guides/language/language-tour

工作示例

class Peoples {
  late int id;
  late String name;

  static final Peoples _inst = Peoples._internal();

  Peoples._internal();
  

  factory Peoples(int id, String name) {
    _inst.id = id;
    _inst.name = name;
    return _inst;
  }
}

void main() {
  print("Instance of = " + Peoples(0, "Dylan").name);
  print("Instance of = " + Peoples(1, "Joe").name);
  print("Instance of = " + Peoples(2, "Maria").name);
}

4
投票

我想回答展示一种通过向其传递参数来创建单例的方法,以及如何在第一次创建单例后“锁定”其值。

class People {
  static final People _inst = People._internal();
  People._internal();

  factory People(int id, String name) {
    assert(!_inst._lock, "it's a singleton that can't re-defined");
    _inst.id = id;
    _inst.name = name;
    _inst._lock = true;
    return _inst;
  }
  
  int id;
  String name;
  bool _lock = false;
}

void main() {
  var people = People(0, 'Dylan');
  try{
    print('Instance of = ' + People(0, 'Joe').name);
    print('Instance of = ' + People(1, 'Maria').name);
    print('Instance of = ' + People(2, 'Ete sech').name);
  } finally {
    print('Instance of = ' + people.name);
  }
}

3
投票

带有无法更改参数的 Dart / Flutter 单例

这是一个类的实例,在第一次构造后总是返回相同的值。

类字段不是final或late,而是可以为空的。

  • 工厂构造函数只允许实例变量为 null 时进行更改。
  • 工厂构造函数为实例变量提供默认值(如果未提供)。
class SingletonClass {
  bool? debugMode;

  /// Always return a singleton instance
  static final SingletonClass _instance = SingletonClass._internal();

  /// Internal Constructor
  SingletonClass._internal();

  /// Consumable Constructor
  factory SingletonClass({bool debugMode = false}) {
    // Set null class parameters
    _instance.debugMode ??= debugMode;

    return _instance;
  }
}
// Initialize the singleton
SingletonClass singletonClass = SingletonClass(debugMode: true);
debugPrint("debugMode: ${singletonClass.debugMode}");

/// Attempt to create another instance with different arguments / field values
SingletonClass singletonClass2 = SingletonClass(debugMode: false);
debugPrint("debugMode2: ${singletonClass2.debugMode}");

控制台日志输出

flutter: debugMode: true
flutter: debugMode2: true

即使第二次创建类的尝试将其声明为 false,debugMode 仍保持为 true。

singletonClass
singletonClass2
都会返回该类的相同实例。

您可以在需要访问其参数的代码中的任何位置声明一个新的

SingletonClass
类型变量,并且它将是相同的。


1
投票

答案无法在我的机器上运行,2022年3月29日

计算机说:“必须初始化不可为 null 的实例字段 'id'。”

我无法发表评论,所以写下这个答案:

在成员变量之前添加关键字

late
会有帮助:

class Peoples {
  late int id;
  late String name;

  static final Peoples _inst = Peoples._internal();

  Peoples._internal();


  factory Peoples(int id, String name) {
    _inst.id = id;
    _inst.name = name;
    return _inst;
  }
}


0
投票
class BasketService {
  late String basketId;

  static final BasketService _instance = BasketService._internal();
  BasketService._internal();

  factory BasketService(String basketUniqueId) {
    _instance.basketId = basketUniqueId;
    return _instance;
  }
  factory BasketService.getInstance() {
    return _instance;
  }
}

0
投票

如果您还想传递一些变量,您可以执行如下操作:

class Person {
  const Person._({
    required String name,
    required String lastname,
  })  : _name = name,
        _lastname = lastname;

  static Person? _instance;

  final String _name;
  final String _lastname;

  factory Person.getInstance({
    required String name,
    required String lastname,
  }) =>
      _instance ??= Person._(name: name, lastname: lastname);

  String get name => _name;
  String get lastname => _lastname;

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.