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