504 Stimmen

Wie baut man ein Singleton in Dart?

Das Singleton-Muster stellt sicher, dass immer nur eine Instanz einer Klasse erstellt wird. Wie baue ich das in Dart?

9voto

sultanmyrza Punkte 2923

So implementiere ich Singleton in meinen Projekten

Inspiriert von Flutter Firebase => FirebaseFirestore.instance.collection('collectionName')

class FooAPI {
  foo() {
    // some async func to api
  }
}

class SingletonService {
  FooAPI _fooAPI;

  static final SingletonService _instance = SingletonService._internal();

  static SingletonService instance = SingletonService();

  factory SingletonService() {
    return _instance;
  }

  SingletonService._internal() {
    // TODO: add init logic if needed
    // FOR EXAMPLE API parameters
  }

  void foo() async {
    await _fooAPI.foo();
  }
}

void main(){
  SingletonService.instance.foo();
}

Beispiel aus meinem Projekt

class FirebaseLessonRepository implements LessonRepository {
  FirebaseLessonRepository._internal();

  static final _instance = FirebaseLessonRepository._internal();

  static final instance = FirebaseLessonRepository();

  factory FirebaseLessonRepository() => _instance;

  var lessonsCollection = fb.firestore().collection('lessons');

  // ... other code for crud etc ...
}

// then in my widgets
FirebaseLessonRepository.instance.someMethod(someParams);

9voto

Jacob Phillips Punkte 8085

Hier ist ein kurzes Beispiel, das die anderen Lösungen kombiniert. Der Zugriff auf das Singleton kann durch erfolgen:

  • Mit einer singleton globale Variable, die auf die Instanz zeigt.
  • Die gemeinsame Singleton.instance Muster.
  • Verwendung des Standardkonstruktors, der eine Fabrik ist, die die Instanz zurückgibt.

Anmerkung: Sie sollten nur eine der drei Optionen implementieren, damit der Code, der das Singleton verwendet, konsistent ist.

Singleton get singleton => Singleton.instance;
ComplexSingleton get complexSingleton => ComplexSingleton._instance;

class Singleton {
  static final Singleton instance = Singleton._private();
  Singleton._private();
  factory Singleton() => instance;
}

class ComplexSingleton {
  static ComplexSingleton _instance;
  static ComplexSingleton get instance => _instance;
  static void init(arg) => _instance ??= ComplexSingleton._init(arg);

  final property;
  ComplexSingleton._init(this.property);
  factory ComplexSingleton() => _instance;
}

Wenn Sie eine komplexe Initialisierung durchführen müssen, müssen Sie dies einfach tun, bevor Sie die Instanz später im Programm verwenden.

Beispiel

void main() {
  print(identical(singleton, Singleton.instance));        // true
  print(identical(singleton, Singleton()));               // true
  print(complexSingleton == null);                        // true
  ComplexSingleton.init(0); 
  print(complexSingleton == null);                        // false
  print(identical(complexSingleton, ComplexSingleton())); // true
}

9voto

thisisyusub Punkte 630

Seit Dart 2.13 Version, ist es sehr einfach mit late Stichwort. Late ermöglicht es uns, Objekte nachlässig zu instanziieren.

Sie können es als Beispiel sehen:

class LazySingletonExample {
  LazySingletonExample._() {
    print('instance created.');
  }

  static late final LazySingletonExample instance = LazySingletonExample._();

}

Hinweis: Beachten Sie, dass es nur einmal instanziiert wird, wenn Sie lazy instance Feld.

8voto

DazChong Punkte 3385

Geänderte Antwort von @Seth Ladd auf die Frage, wer den Swift-Stil von Singleton bevorzugt, wie .shared :

class Auth {
  // singleton
  static final Auth _singleton = Auth._internal();
  factory Auth() => _singleton;
  Auth._internal();
  static Auth get shared => _singleton;

  // variables
  String username;
  String password;
}

Beispiel:

Auth.shared.username = 'abc';

8voto

Maxim Saplin Punkte 2909

Wenn Sie Flutter verwenden und provider Paket für die Zustandsverwaltung ist das Erstellen und Verwenden eines Singletons recht einfach.

  1. Eine Instanz erstellen
  void main() {
      runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (context) => SomeModel()),
            Provider(create: (context) => SomeClassToBeUsedAsSingleton()),
          ],
          child: MyApp(),
        ),
      );
    }
  1. Holen Sie die Instanz
Widget build(BuildContext context) { 
  var instance = Provider.of<SomeClassToBeUsedAsSingleton>(context); 
  ...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X