Singleton in Flutter

- Andrés Cruz

En español
Singleton in Flutter

Simply put, a singleton ensures that a class has only one instance in all applications and provides a global access point.

An instance or object of a Class is a concrete and specific representation of a Class

The Singleton pattern is one of many design patterns that guarantees that a class has only one instance; and it is basically that; for this, object-oriented programming is used. In Flutter, the Singleton pattern is often used in combination with the Material layout to provide global access to certain Material widgets used in the app.

For example, a singleton DatabaseHelper can be used to provide global access to an SQLite database; this is an implementation that I commonly do in the Flutter course and in my apps; These types of adaptations are common in Flutter and facilitate the process of creating organized, modular and scalable applications.

In general, the implementation of a Singleton pattern in Flutter follows the same principles as in any other programming language, ensuring that only one instance of a given class is created, and providing a global access point for that instance.

When to use it?

This pattern is used when we need only one instance of something in our application. For example, in the case of a user login in our application, we need this information in several parts, but it would be too expensive in terms of processing to have the user information for each flow. In this case we can create a user singleton and it would be the same instance for all streams.

Benefits

  • Controlled access to a single instance of data. That is, you can have strict control over how and when clients access.
  • The instance is created only when it is to be used.
  • Accessible from anywhere, singleton is an improvement over global variables.

How do we guarantee that a Class has only one instance?

One solution is to make the Class itself responsible for its only instance. The Class can ensure that no other instance can be created and must provide a way to access the instance.

Singleton in Flutter

One way to create a singleton in Dart is to use factory constructors. As an example, let's create a user singleton that will hold the username. To do this, we first create a regular Class called UserSingleton. We make it a singleton by creating a private variable _instance of type UserSingleton. We then create it using a UserSingleton() factory that returns the instance.

Finally, we create the UserSingleton._internal() constructor which is called exactly once, and since it is private it can only be called in this Class and we also prevent it from being instantiated outside of here. This constructor can be used to initialize the logic.

In the example we are going to use, we also have a method to update the username.

Finally, the UserSingleton is as follows:

class UserSingleton {
  static final UserSingleton _instance = UserSingleton._internal();
  String userName = 'Alvaro';
  // using a factory is important
  // because it promises to return _an_ object of this type
  // but it doesn't promise to make a new one.
  factory UserSingleton() {
    return _instance;
  }
  // This named constructor is the "real" constructor
  // It'll be called exactly once, by the static property assignment         above
  // it's also private, so it can only be called in this class
  UserSingleton._internal() {
    // initialization logic
  }
  // rest of class as normal, for example:
  void updateUserName(String name) {
    userName = name;
  }
}

Here you can see another Singleton implementation for a database helper:

class DatabaseHelper {
 static DatabaseHelper _instance;
 factory DatabaseHelper() => _instance ??= DatabaseHelper._();
 DatabaseHelper._();
 // aquí puedes agregar métodos y propiedades relacionados con la base de datos
}

In this example, the DatabaseHelper class has a static class property _instance that contains the single instance of the class. A factory constructor is used to create a new instance of the class if it doesn't already exist, or to return the existing instance if it has already been created.

Remember that…

Using factory constructors in Dart is used when you don't need to create an instance of the class itself or where you have an instance of a subclass or the same class,

By using the factory constructor, you can control how the class is instantiated, and can often optimize and reuse the same instance for subsequent calls. This can be useful in situations where creating a new instance of a class can be costly in terms of time and resources.

The current DatabaseHelper._() constructor is private, which means it cannot be called from outside the class, forcing an instance to be created via the /factory constructor.

To use the DatabaseHelper in your application, simply call the factory constructor, as shown below:

DatabaseHelper db = DatabaseHelper();

In this way, only one instance of the DatabaseHelper class can be created, and it can be accessed anywhere in the application.

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.