单例模式确保只创建一个类的实例。我如何在达特建立这个?


当前回答

多亏了Dart的工厂构造函数,构建一个单例对象变得很容易:

class Singleton {
  static final Singleton _singleton = Singleton._internal();

  factory Singleton() {
    return _singleton;
  }

  Singleton._internal();
}

你可以这样构造它

main() {
  var s1 = Singleton();
  var s2 = Singleton();
  print(identical(s1, s2));  // true
  print(s1 == s2);           // true
}

其他回答

我觉得阅读new Singleton()不是很直观。你必须阅读文档才能知道new实际上并没有像通常那样创建一个新实例。

这里有另一种方法来做单例(基本上是Andrew上面说的)。

lib / thing.dart

library thing;

final Thing thing = new Thing._private();

class Thing {
   Thing._private() { print('#2'); }
   foo() {
     print('#3');
   }
}

main.dart

import 'package:thing/thing.dart';

main() {
  print('#1');
  thing.foo();
}

注意,由于Dart的惰性初始化,直到第一次调用getter时才创建单例。

如果你愿意,你也可以在单例类上作为静态getter来实现单例。即的事情。单例,而不是顶级getter。

还可以阅读Bob Nystrom在他的游戏编程模式书中对单身人士的看法。

在这个例子中,当我想要使用Singleton时,我做了其他必要的事情。例如:

将一个值传递给单例对象的构造函数 在构造函数内部初始化一个值 为Singleton的变量设置一个值 能够访问和访问这些值。

是这样的:

class MySingleton {

  static final MySingleton _singleton = MySingleton._internal();

  String _valueToBeSet;
  String _valueAlreadyInSingleton;
  String _passedValueInContructor;

  get getValueToBeSet => _valueToBeSet;

  get getValueAlreadyInSingleton => _valueAlreadyInSingleton;

  get getPassedValueInConstructor => _passedValueInContructor;

  void setValue(newValue) {
    _valueToBeSet = newValue;
  }

  factory MySingleton(String passedString) {
    _singleton._valueAlreadyInSingleton = "foo";
    _singleton._passedValueInContructor = passedString;

    return _singleton;
  }

  MySingleton._internal();
}

MySingleton的用法:

void main() {

MySingleton mySingleton =  MySingleton("passedString");
mySingleton.setValue("setValue");
print(mySingleton.getPassedValueInConstructor);
print(mySingleton.getValueToBeSet);
print(mySingleton.getValueAlreadyInSingleton);

}

多亏了Dart的工厂构造函数,构建一个单例对象变得很容易:

class Singleton {
  static final Singleton _singleton = Singleton._internal();

  factory Singleton() {
    return _singleton;
  }

  Singleton._internal();
}

你可以这样构造它

main() {
  var s1 = Singleton();
  var s2 = Singleton();
  print(identical(s1, s2));  // true
  print(s1 == s2);           // true
}

如果碰巧使用Flutter和提供程序包进行状态管理,则创建和使用单例非常简单。

创建实例

无效主体(){ runApp ( MultiProvider ( 供应商:[ ChangeNotifierProvider(create: (context) => SomeModel()), Provider(create: (context) => SomeClassToBeUsedAsSingleton()), ], 孩子:MyApp (), ), ); }

获取实例

Widget build(BuildContext context) { var instance = Provider.of<SomeClassToBeUsedAsSingleton>(context); ...

这里有一个简单的答案:

类应具有其类型的私有和静态属性。 构造函数应该是私有的,以防止外部对象初始化。 检查实例是否为空,如果是,创建一个实例并返回,否则返回现有实例。

实现(延迟加载)

class Singleton {
  static Singleton? _instance;

  Singleton._();

  static Singleton get instance => _instance ??= Singleton._();

  void someMethod(){
    ...
  }

  ...
}

实现(急装)

class Singleton {
  static Singleton _instance = Singleton._();

  Singleton._();

  static Singleton get instance => _instance;

  void someMethod(){
    ...
  }

  ...
}

使用

Singleton.instance.someMethod();