dart - Why use the factory constructor in this case - TagMerge
3Why use the factory constructor in this caseWhy use the factory constructor in this case

Why use the factory constructor in this case

Asked 5 months ago
4
3 answers

I don't see a need to use factory in that example. It could have been a normal named constructor:

Content.fromJson(Map<String, dynamic> json) : this(title: json["title"]);

That said, even if unnecessary, declaring the constructor as a factory constructor would leave open the possibility that someday it could return an existing instance instead of guaranteeing a new instance.

Of course, in this case, a factory constructor is also unnecessary since it could also be a static method (which could provide other benefits).

Source: link

0

Then why some people use:
factory User.fromJson(Map<String, dynamic> json) =>
      User(name: json['name'], alias: json['alias']);
instead of the more reasonable:
User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        alias = json['alias'];
Say you create a User class like so:
class User {
  User({this.name, this.alias});

  User.fromJson(Map<String, dynamic> json) {
    return User(name: json['name'], alias: json['alias']);
  }

  final String name;
  final String alias;
}
The User.fromJson constructor is a generative constructor. One characteristic of generative constructors is that you can forward to them from another constructor. That means someone else can subclass your class like so:
class SoftwareUser extends User {
  SoftwareUser(Map<String, dynamic> json) : super.fromJson(json);
}
But later you decide that you'd like to do a bit of error checking and text manipulation on that JSON map before you try to create an object from it. You can do a little with asserts but you're limited. Factory constructors, on the other hand, would allow you to do a lot more. Here's an example of doing a more work in the constructor:
class User {
  User({this.name, this.alias});

  factory User.fromJson(Map<String, dynamic> json) {
    String userName = json['name'];
    String userAlias = json['alias'];
    if (userName == null || userAlias == null) throw FormatException();
    userName = userName.toUpperCase();
    userAlias = userAlias.toUpperCase();
    return User(name: userName, alias: userAlias);
  }

  final String name;
  final String alias;
}

Source: link

0

In Dart, we can write multiple constructors for a class which allows different types of initialization. Writing factory keyword in front of a normal constructor or a named constructor will make it a factory constructor.
class MyClass {
   // ...
   factory MyClass() {
     //..
   }
}
The is the first use case where the constructor is expensive and you want to avoid the expensive work if possible. And this works exactly like a warehouse. Let’s say there is a warehouse for expensive shoes and a customer ordered a pair of shoes. Now the warehouse owner first looks if he has the stock available for that particular product. If it is available then he will deliver the order immediately. Otherwise, he will ask the production team to build new ones. This is exactly how the first use case works.
class Product {
  
  // private cache
  static final _shelf = <String, Product>{};
  
  factory Product(String productId) {
     return _shelf.putIfAbsent(
        productId, () => Product._buildNewProduct(productId));
  }
  
  Product._buildNewProduct(String productId) {
    //..
  }
  
}
This is useful when only one instance of that class is needed throughout the application. The most common use case is a local storage database. We need only a single instance of that class throughout the application.
class LocalStorage {
 
  static final _instance = LocalStorage._internal();
  
  factory LocalStorage() {
     return _instance;
  }
  
  LocalStorage._internal();
  
  Future<void> save(key, val) async {
    //.. 
  }
  
  Future read(key) async {
    //..
  }
}
There will be situations where you need to return subclass instance where constructor will act like instance factory which return apporpriate subclass based on provided input.
abstract class Shape {
  double area();

  factory Shape.fromType(String type) {
    if (type == 'square') return Square();
    if (type == 'circle') return Circle();
    throw Exception("unknown type");
  }
}

class Square implements Shape {
  double side = 5;
  
  @override
  double  area() => pow(side, 2);
  
}

class Circle implements Shape {
  double radius = 5;
  
  @override
  double  area() => pi * pow(radius, 2);
}
You can use the abstract base class for returning subclass instances based on how the factory constructer is called. This is a simplied way to using the popular fatory design pattern.
var shape = Shape.fromType("square");
print(shape.area());

Source: link

Recent Questions on dart

    Programming Languages