Flutter:什么时候应该使用工厂构造函数?

森口万*_*万太郎 7 dart flutter

https://flutter.dev/docs/cookbook/networking/fetch-data

在上一页的最后一个“完整示例”中,

class Album {
  final int userId;
  final int id;
  final String title;

  Album({this.userId, this.id, this.title});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

它是一个Album类,用于接收请求中收到的JSON字符串并在应用程序中处理它,构造函数除了普通构造函数之外还提供了工厂构造函数。

关于工厂构造函数, https://dart.dev/guides/language/language-tour#constructors

我已阅读上一页的工厂构造函数部分。

示例中Logger类的工厂构造函数并不总是创建新实例,因此我可以理解添加factory关键字,

即使在这个 Complete 示例的 Album 类中,是否也有必要使用工厂构造函数?

对于Album类,由于在工厂构造函数中使用了普通构造函数,因此我觉得这个工厂构造函数(Album.fromJson)总是创建一个新实例。实际上

Future<Album> fetchAlbum() async {
  final response =
  await http.get('https://jsonplaceholder.typicode.com/albums/16');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    var temp=json.decode(response.body);
    return Album(userId:temp['userId'],id:temp['id'],title:temp['title']);
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,即使我尝试仅使用普通构造函数,它似乎也可以正常工作。

准备和使用工厂构造函数有什么好处吗?

或者在这种情况下不使用工厂构造函数是否有问题?

我不确定什么时候首先使用工厂构造函数,有明确的定义吗?

Abd*_*man 6

在深入了解Flutter 中的工厂作为关键字之前,您可以先看看工厂作为设计模式,以了解全貌。

\n

使用工厂设计模式的主要好处

\n
\n

也就是说,工厂方法设计模式为负责创建对象的类定义了一个接口,因此将实例化推迟到实现该接口的特定类。这解决了直接在使用它们的类中创建对象的问题。\n此外,它还通过子类化实现了编译时灵活性。当在类中创建对象时,它非常不灵活,因为您无法独立于类 \xe2\x80\x94 来更改对象的实例化,该类已提交给特定对象。通过实现该模式,可以编写子类来重新定义对象的创建方式。

\n
\n

欲了解更多信息,请参阅此处

\n

正如文档所指

\n
\n

在实现不总是创建其类的新实例的构造函数时,请使用工厂关键字。例如,工厂构造函数可能会从缓存返回一个实例,也可能会返回一个子类型的实例。工厂构造函数的另一个用例是使用不能在初始化列表中处理的逻辑来初始化最终变量。

\n
\n

所以这一切都是为了向外界隐藏创作逻辑。

\n

当然你可以执行以下操作

\n
return Album(userId:temp[\'userId\'],id:temp[\'id\'],title:temp[\'title\']);\n
Run Code Online (Sandbox Code Playgroud)\n

但是,如果您在许多不同的组件或类中这样做,那么每当您更改创建背后的逻辑时Album您都需要在所有地方更改它。

\n

另一方面,使用类的类Album只关心有一个Objectof Album,他们不关心它是如何实例化的,所以如果你把拥有一个实例的逻辑放在类本身之外,你就会陷入所谓的意大利面条代码

\n