What kinds of constructors exist in Dart (default, named, `factory`) and what is each one for?
Show answer — try answering out loud first
Dart has the default constructor (the one with the class name), named constructors (to have several ways of creating the object), and the factory constructor (which can decide which instance to return, even an existing one). On top of that, there's syntactic sugar for assigning properties directly from the parameters.
- Default constructor: the classic one. Dart lets you shorten the assignment with
this.propertyin the parameters. - Named constructor (
Class.name()): useful for creating the object in different ways (for example,Point.origin()orColor.fromHex()). factory: it's not required to create a new instance. It can return a cached one, a subclass, or build from another source. It's used a lot in singleton patterns and infromJson.- Initializer list (
: field = value): assignsfinalfields before the constructor body runs.
class Point {
final double x;
final double y;
// Default constructor with syntactic sugar
Point(this.x, this.y);
// Named constructor
Point.origin()
: x = 0,
y = 0;
// Factory: decides what to return
factory Point.fromMap(Map<String, double> map) {
return Point(map["x"] ?? 0, map["y"] ?? 0);
}
@override
String toString() => "Point($x, $y)";
}
void main() {
print(Point(3, 4)); // Point(3.0, 4.0)
print(Point.origin()); // Point(0.0, 0.0)
print(Point.fromMap({"x": 1, "y": 2})); // Point(1.0, 2.0)
}
Confusing a normal constructor with a factory. A normal constructor always creates a new instance and can't have a return. A factory must have a return and can return an already existing instance. Trying to put a return in a normal constructor is a classic error.
"Dart has the default constructor, which can shorten the assignment with
this.xin the parameters; named constructors likePoint.origin()to have several ways of creating the object; and thefactoryconstructor, which unlike a normal one isn't required to create a new instance: it can return a cached one or build from a JSON. That's whyfactoryis common in singletons and in thefromJsonof models."
Why is factory typically used to implement a singleton?
See answer
Because a factory can always return the same instance instead of creating a new one. You store a private static instance and the factory returns it every time:
class Config {
static final Config _instance = Config._internal();
factory Config() => _instance;
Config._internal();
}
Every Config() returns the same object.