HelpSingleton class abstract

Help with Singletons in Flutter & Dart.

Singletons are classes where there can only be one instance, e.g. FirebaseAuth.instance

Creating Singletons

There are a few ways in which Singletons can be created:

Static field

Shortest and cleanest method.

class SingletonStaticFinal {
  SingletonStaticFinal._privateConstructor();

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

SingletonStaticFinal three = SingletonStaticFinal.instance;

Static field with getter

Having the getter would allow you to do other work before returning the instance.

class SingletonGetterExample {
  SingletonGetterExample._privateConstructor();
  static final SingletonGetterExample _instance = SingletonGetterExample._privateConstructor();
  static SingletonGetterExample get instance {
    return _instance;
  }
}

SingletonGetterExample two = SingletonGetterExample.instance;

Factory

When instantiated, looks like any other class. You could use this one if you want to hide the fact that it is a singleton (and leave the option to make it not be a singleton in the future). You could also pass in arguments in the constructor.

class SingletonFactoryExample {
  SingletonFactoryExample._privateConstructor();

  static final SingletonFactoryExample _instance = SingletonFactoryExample._privateConstructor();

  factory SingletonFactoryExample() {
    return _instance;
  }
}

SingletonFactoryExample one = SingletonFactoryExample();

Usage

Singletons are often a reasonable solution for library or package design, but care should be taken when using it in application code.

Advantages

  • Flutter apps have deeply nested widget trees; and singletons make it easy to access the objects from any widget.

Disadvantages

Singletons are hard to test

Singletons are Implicit Dependencies

  • May become difficult to spot for uninitiated when code base becomes large
class FirebaseAuthRepository {
  Future<void> signOut() => FirebaseAuth.instance.signOut();
}
class FirebaseAuthRepository {
  // easy to find the dependencies here,
  // even if this class becomes very large
  const FirebaseAuthRepository(this._auth);
  final FirebaseAuth _auth;
  Future<void> signOut() => _auth.signOut();
}

Instance Lifecycle

  • When we initialize a singleton instance, it will remain alive until the end of time (a.k.a. when the application is closed). And if the instance consumes a lot of memory or keeps an open network connection, we can't release it early if we want to.

Thread Safety

References

Constructors

HelpSingleton()

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited