¿Cómo se construye un Singleton en Dart?

Resuelto Seth Ladd asked hace 11 años • 30 respuestas

El patrón singleton garantiza que solo se cree una instancia de una clase. ¿Cómo construyo esto en Dart?

Seth Ladd avatar Sep 29 '12 09:09 Seth Ladd
Aceptado

Gracias a los constructores de fábrica de Dart , es fácil construir un singleton:

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

Puedes construirlo así.

main() {
  var s1 = Singleton();
  var s2 = Singleton();
  print(identical(s1, s2));  // true
  print(s1 == s2);           // true
}
Seth Ladd avatar Sep 29 '2012 02:09 Seth Ladd

A continuación se muestra una comparación de varias formas diferentes de crear un singleton en Dart.

1. Constructor de fábrica

class SingletonOne {

  SingletonOne._privateConstructor();

  static final SingletonOne _instance = SingletonOne._privateConstructor();

  factory SingletonOne() {
    return _instance;
  }

}

2. Campo estático con getter

class SingletonTwo {

  SingletonTwo._privateConstructor();

  static final SingletonTwo _instance = SingletonTwo._privateConstructor();

  static SingletonTwo get instance => _instance;
  
}

3. Campo estático

class SingletonThree {

  SingletonThree._privateConstructor();

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

Cómo crear una instancia

Los singletons anteriores se crean instancias de esta manera:

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

Nota:

Originalmente hice esto como una pregunta , pero descubrí que todos los métodos anteriores son válidos y la elección depende en gran medida de las preferencias personales.

Suragch avatar Mar 26 '2019 00:03 Suragch

Aquí hay una respuesta simple:

  • La clase debe tener una propiedad privatey staticde su tipo.
  • El constructor debe privateevitar la inicialización de objetos externos.
  • Compruebe si la instancia es null, en caso afirmativo, cree una instancia y devuélvala ; de lo contrario, devuelva la instancia existente .

Implementación (contratista de fábrica)

class Singleton {
  static Singleton? _instance;

  Singleton._();

  factory Singleton() => _instance ??= Singleton._();

  void someMethod() {
    // ...
  }
}

Uso

Singleton().someMethod();

// prints "Same Singleton instance? true"
print('Same Singleton instance? ${Singleton().hashCode == Singleton().hashCode}');

Implementación (carga diferida)

class Singleton {
  static Singleton? _instance;

  Singleton._();

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

  void someMethod() {
    ...
  }

  ...
}

Implementación (carga ansiosa)

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

  Singleton._();

  static Singleton get instance => _instance;

  void someMethod() {
    ...
  }

  ...
}

Uso

Singleton.instance.someMethod();
Hamed avatar Nov 25 '2019 06:11 Hamed

No me parece una lectura muy intuitiva new Singleton(). Debe leer los documentos para saber que newen realidad no se está creando una nueva instancia, como lo haría normalmente.

Aquí hay otra forma de hacer singletons (básicamente lo que Andrew dijo anteriormente).

lib/cosa.dart

library thing;

final Thing thing = new Thing._private();

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

dardo.principal

import 'package:thing/thing.dart';

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

Tenga en cuenta que el singleton no se crea hasta la primera vez que se llama al captador debido a la inicialización diferida de Dart.

Si lo prefiere, también puede implementar singletons como captadores estáticos en la clase singleton. es decir Thing.singleton, en lugar de un captador de nivel superior.

Lea también la versión de Bob Nystrom sobre los singletons de su libro de patrones de programación de juegos .

Greg Lowe avatar Dec 12 '2013 23:12 Greg Lowe