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


当前回答

你好,这样的东西怎么样?非常简单的实现,Injector本身是单例的,并且还添加了类。当然可以很容易地扩展。如果您正在寻找更复杂的东西,请检查这个包:https://pub.dartlang.org/packages/flutter_simple_dependency_injection

void main() {  
  Injector injector = Injector();
  injector.add(() => Person('Filip'));
  injector.add(() => City('New York'));

  Person person =  injector.get<Person>(); 
  City city =  injector.get<City>();

  print(person.name);
  print(city.name);
}

class Person {
  String name;

  Person(this.name);
}

class City {
  String name;

  City(this.name);
}


typedef T CreateInstanceFn<T>();

class Injector {
  static final Injector _singleton =  Injector._internal();
  final _factories = Map<String, dynamic>();

  factory Injector() {
    return _singleton;
  }

  Injector._internal();

  String _generateKey<T>(T type) {
    return '${type.toString()}_instance';
  }

  void add<T>(CreateInstanceFn<T> createInstance) {
    final typeKey = _generateKey(T);
    _factories[typeKey] = createInstance();
  }

  T get<T>() {
    final typeKey = _generateKey(T);
    T instance = _factories[typeKey];
    if (instance == null) {
      print('Cannot find instance for type $typeKey');
    }

    return instance;
  }
}

其他回答

** Sigleton范式在Dart声音零安全**

这段代码片段展示了如何在dart中实现单例 这通常用于每次必须使用同一个类的相同对象的情况。在数据库事务。

class MySingleton {
  static MySingleton? _instance;
  MySingleton._internal();
  factory MySingleton() {
    if (_instance == null) {
      _instance = MySingleton._internal();
    }
     return _instance!;
  }
}

下面是在Dart中创建单例对象的几种不同方法的比较。

1. 工厂构造函数

class SingletonOne {

  SingletonOne._privateConstructor();

  static final SingletonOne _instance = SingletonOne._privateConstructor();

  factory SingletonOne() {
    return _instance;
  }

}

2. 带有getter的静态字段

class SingletonTwo {

  SingletonTwo._privateConstructor();

  static final SingletonTwo _instance = SingletonTwo._privateConstructor();

  static SingletonTwo get instance => _instance;
  
}

3.静态字段

class SingletonThree {

  SingletonThree._privateConstructor();

  static final SingletonThree instance = SingletonThree._privateConstructor();
  
}

如何实例化

上面的单例是这样实例化的:

SingletonOne one = SingletonOne();
SingletonTwo two = SingletonTwo.instance;
SingletonThree three = SingletonThree.instance;

注意:

我最初是把这个作为一个问题来问的,但发现上面所有的方法都是有效的,选择在很大程度上取决于个人喜好。

由const构造函数和工厂组成的Dart单例

class Singleton {
  factory Singleton() =>
    Singleton._internal_();
  Singleton._internal_();
}
 
 
void main() {
  print(new Singleton() == new Singleton());
  print(identical(new Singleton() , new Singleton()));
}

在库中使用全局变量怎么样?

single.dart:

library singleton;

var Singleton = new Impl();

class Impl {
  int i;
}

main.dart:

import 'single.dart';

void main() {
  var a = Singleton;
  var b = Singleton;
  a.i = 2;
  print(b.i);
}

或者这是不受欢迎的?

单例模式在Java中是必要的,因为在Java中不存在全局变量的概念,但在Dart中似乎不需要绕这么长的路。

我觉得阅读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在他的游戏编程模式书中对单身人士的看法。