Dart/Flutter: What Are Factory Constructors? (Advanced Knowledge)
You will learn how factory constructors work and when to use them.

Table of Contents
Introduction When to use them? ↳ Singleton pattern ↳ Deserialization ↳ Instantiate subclass ↳ Syntax sugar What is the difference between a factory constructor and a static method? Conclusion Resources More articles
Introduction
Factory constructors are nothing you need to program a Flutter app. Nevertheless, they can be useful for different use cases. Factory constructors can be helpful to implement the singleton pattern, use deserialization, instantiate subclasses, or improve readability. Often factory constructors and static methods look like they are the same. After reading the article you will understand the differences. In general, this is a more advanced topic that addresses people with a basic understanding of Dart (and Flutter) who want to expand their knowledge.
When to use them?
In the following, I describe different use cases for which factory constructors make sense with code examples.
Singleton pattern
If you implement the singleton pattern, you only allow to instantiate one object of a class. This makes sense if you have complex classes that require heavy computation or allow only one access, e.g. for a database for which an example is provided in the following. You can play around with the following example on this DartPad.
The database object is created at (1). The creation of an object can only be done once inside the class because of “._internal” (2). When you the factory it always returns the same database object (3). Using factories is an easy way to implement singletons.
class Database {
static final Database _database = Database._internal(); // (1)
factory Database() => _database; // (3)
Database._internal(); // (2)
}
// Create the singleton
void main() {
Database db = Database();
Database db2 = Database();
print(identical(db, db2)); // true
}Deserialization
Most apps need API calls. When you get the information as a map you most often want to create classes to continue working with the information. With a factory, you can take a map as input and give an object as output. You can try the example of the deserialization of a user on this DartPad.
In the example, you extract the user data from a map (1), which is a quite common scenario. When the factory is called (2) it maps the chosen keys as attributes of a user object (3).
class User {
final String name;
final int age;
User({required this.name, required this.age});
factory User.fromJson(Map<String, dynamic> json) => User(
name: json['name'],
age: json['age'],
); // (3)
}
// Use deserialization
void main() {
final karlMap = {
'name': 'Karl',
'age': 32,
}; // (1)
final karl = User.fromJson(karlMap); // (2)
print(karl.name); // Karl
print(karl.age); // 32
}Instantiate subclass
With factory constructors, you can instantiate different subclasses of your parent class. This can be useful if you want to create a subclass randomly or depending on time.
Imagine you want to create a game. In this game, you encounter at first easy enemies that get more powerful as time goes by. A ghost (1) is an easy enemy and a dragon (2) is a difficult enemy. As time progresses, the game becomes more difficult and you encounter more dragons (3,4). This can also be done by letting a static method decide which subclass should be returned but with a factory constructor, this can be implemented slightly more elegant. Here is how you could implement this with code. You can try it on this DartPad.
class Enemy {
final int strength = 0;
final String name = '';
factory Enemy.getEnemy({required int timeInSeconds}) {
if (timeInSeconds < 1000) {
return Ghost();
} else {
return Dragon();
}
}
}
class Ghost implements Enemy { // (1)
@override
final int strength = 10;
@override
final String name = "Ghost";
}
class Dragon implements Enemy { // (2)
@override
final int strength = 100;
@override
final String name = "Dragon";
}
void main() {
Enemy enemy = Enemy.getEnemy(timeInSeconds: 1); // (3)
print(enemy.strength); // prints 10
print(enemy.name); // prints Ghost
Enemy enemy2 = Enemy.getEnemy(timeInSeconds: 1000); // (4)
print(enemy2.strength); // prints 100
print(enemy2.name); // prints Dragon
}Syntax sugar
Sometimes it makes sense to use a factory constructer over a static function because the syntax is easier to write and understand. The differences get covered in the following chapter What is the difference between a factory constructor and a static method?
What is the difference between a factory constructor and a static method?
Most often, a factory could also be replaced by a static method. So why do you need factory constructors? Flutter legend Remi Rousselet, creator of packages like provider, riverpod, and freezed, wrote a great article about The difference between a “factory constructor” and a “static method”. I just list his findings here. For further explanations and code examples, I want to reference his blog post.
Remi Rousselets’ package freezed uses the factory constructor in combination with code generation. I recommend looking at the syntax after reading his article to see how he used the factory constructor in combination to speed up your development process.
- Factory constructors can be unnamed.
- A factory constructor doesn’t need to specify the generic parameters.
- Specifying a factory-named constructor removes the default constructor.
- Factory constructors have a short-hand syntax for redirecting to another constructor.
- Factory constructors can be declared as
const. - Factory constructors can’t be async. (This point is from the comments of the article)
Conclusion
Factory constructors most often can be replaced by static methods. For some use cases, they have an advantage because the code is easier to write and read. This can be the case for singletons or for instantiating subclasses. Do you have questions or something to add? Then share your thoughts in the comments. Also, let me know if you have a topic in mind that I should cover in my next article. Any feedback is highly appreciated!
If you liked the article clap (50x), highlight, comment, and share it. Not only but especially technical articles got disadvantaged by the new Medium Partner Program incentives. If you want to support your favorite (technical) writers on Medium, remember to interact with the articles. You find more information about this here: The New Medium Partner Program is Bad for Quality Writing!
Resources
- Factory constructors (documentation, Dart)
- Factory Constructors in Dart (YouTube, Programming Point)
- Understanding Factory constructor code example — Dart (StackOverFlow, Ananta K Roy)
- FACTORY CONSTRUCTOR IN DART (blog, dart-tutorial.com)
- THE DIFFERENCE BETWEEN A “FACTORY CONSTRUCTOR” AND A “STATIC METHOD” (blog, dashoverflow [Remi Rousselet])
- How do you build a Singleton in Dart? (StackOverFlow, Seth Ladd)





