我一直在研究我的Flutter应用程序的JSON解析,并且对我无法解决的工厂构造函数有疑问。我试图了解使用工厂构造函数与普通构造函数相比的优势。例如,我看到很多JSON解析示例,这些示例使用JSON构造函数创建模型类,如下所示:
class Student{
String studentId;
String studentName;
int studentScores;
Student({
this.studentId,
this.studentName,
this.studentScores
});
factory Student.fromJson(Map<String, dynamic> parsedJson){
return Student(
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
);
}
}
我也看到了很多相同的示例,它们没有将构造函数声明为工厂。两种类型的classname.fromJSON构造函数都从JSON数据创建对象,因此将构造函数声明为工厂还是在这里使用工厂是多余的?
答案 0 :(得分:9)
普通构造函数总是返回当前类的新实例(除非构造函数抛出异常)。
工厂构造函数与静态方法非常相似,不同之处在于
new
调用new
成为可选参数,因此现在不再那么重要了。: super()
)因此可以使用工厂构造函数
在您的示例中,此代码
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
由于无需初始化final
字段,因此可以移动到普通构造函数的正文中。
答案 1 :(得分:2)
null
。 (不过,some people dislike returning null
from a factory constructor。)new
一起使用。 (但是using new
is now discouraged。)async
。 (工厂构造函数必须返回其类的类型,因此它不能返回Future
。)答案 2 :(得分:1)
在我注意到并想知道同样的问题之后,并且鉴于我不认为其他答案实际上回答了这个问题(“我一直在研究JSON解析[...],我试图了解其优势使用工厂构造函数与普通构造函数的对比”),这是我的尝试:
在解析json时,使用工厂构造函数而不是普通构造函数没有任何优势或区别。我尝试了两种,并且都可以使用所有类型的参数。由于代码编写的便利性和可读性,我最终决定采用工厂构造函数,但这是一个选择问题,两者在所有情况下都可以正常工作。
答案 3 :(得分:0)
工厂构造函数的用途之一是,我们可以在运行时决定创建哪个实例并将所有逻辑移至父级的工厂构造函数
假设您有 1 个父类和 2 个子类
class GolderRetriever extends Dog{
GolderRetriever(String name):super(name);
}
class Labrador extends Dog{
Labrador(String name):super(name);
}
然后我们有父类
class Dog{
final String name;
Dog(this.name);
factory Dog.createInstance({required String name,DogType type=DogType.UNKNOWN}){
if(type==DogType.GOLDEN_RETRIEVER){
return GolderRetriever(name);
}
else if(type==DogType.DALMATION){
return Labrador(name);
}else{
return Dog(name);
}
}
}
而且我还有 enum DogType
enum DogType{
GOLDEN_RETRIEVER,DALMATION,UNKNOWN
}
然后在主方法中,您只需将要创建的子类实例委托给父Dog类
main() {
Dog myDog = Dog.createInstance(name:"Rocky",type:DogType.DALMATION);
Dog myNeighboursDog = Dog.createInstance(name:"Tommy",type:DogType.GOLDEN_RETRIEVER);
Dog strayDog = Dog.createInstance(name:"jimmy");
}
您不能使用命名构造函数来执行此操作,因为您只能创建该类的实例(Dog 类),而不能创建其子类型。
现在创建哪个实例的责任委托给父类。这可以删除很多 if-else 样板代码。当您想更改逻辑时,只需在 Animal 类中更改即可。