[英]dart advantage of a factory constructor identifier
I've been investigating JSON parsing for my Flutter app and have a question about factory constructors that I can't resolve.我一直在为我的 Flutter 应用程序调查 JSON 解析,并且对我无法解决的工厂构造函数有疑问。 I'm trying to understand the advantage of using a factory constructor versus a plain constructor.我试图了解使用工厂构造函数与普通构造函数的优势。 For example, I see quite a few JSON parsing examples that create a model class with a JSON constructor like this:例如,我看到很多 JSON 解析示例创建 model class 和 Z0ECD11C41D7A287A201
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']
);
}
}
I've also seen an equal number of examples that DON'T declare the constructor as a factory.我还看到了相同数量的不将构造函数声明为工厂的示例。 Both types of classname.fromJSON constructors create an object from the JSON data so is there an advantage to declaring the constructor as a factory or is using a factory here superfluous?两种类型的 classname.fromJSON 构造函数都从 JSON 数据创建了 object ,因此将构造函数声明为工厂或在此处使用工厂是多余的吗?
A normal constructor always returns a new instance of the current class (except when the constructor throws an exception).普通构造函数总是返回当前类的一个新实例(除非构造函数抛出异常)。
A factory constructor is quite similar to a static method with the differences that it工厂构造函数与静态方法非常相似,不同之处在于它
new
but that is now less relevant since new
became optional.可以用new
调用,但现在不太相关,因为new
成为可选的。: super()
)没有初始化列表(没有: super()
)So a factory constructor can be used所以可以使用工厂构造函数
In your example this code在您的示例中,此代码
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
could be moved to the body of a normal constructor because no final
fields need to be initialized.可以移动到普通构造函数的主体,因为不需要初始化final
字段。
null
.允许工厂构造函数返回现有实例、派生类的实例或null
。 (However, some people dislike returning null
from a factory constructor . Note that returning null
from a factory constructor is disallowed with null-safety.) (然而, 有些人不喜欢返回null
从工厂构造函数。需要注意的是返回null
从一个工厂的构造是不允许用空安全。)factory
constructors therefore cannot be extended with derived classes.因此,仅提供factory
构造函数的类不能使用派生类进行扩展。new
.工厂构造函数可以与new
一起使用。 (But using new
is now discouraged .) (但现在不鼓励使用new
。)async
.静态方法可以是async
。 (A factory constructor must return a type of its class, so it cannot return a Future
.) (工厂构造函数必须返回其类的类型,因此它不能返回Future
。)const
.工厂构造函数可以声明为const
。After I've been noticing and wondering the same, and given I don't think the other answers actually answer the question ("I've been investigating JSON parsing [...] I'm trying to understand the advantage of using a factory constructor verses a plain constructor"), here my try:在我注意到并想知道同样的问题之后,鉴于我认为其他答案实际上并没有回答这个问题(“我一直在研究 JSON 解析 [...] 我试图了解使用工厂构造函数与普通构造函数相对”),这里是我的尝试:
there's no advantage or difference that I could see or understand, when parsing json, in using a factory constructor instead of a plain constructor.在解析 json 时,使用工厂构造函数而不是普通构造函数没有任何我能看到或理解的优势或差异。 I tried both, and both works fine, with all the types of parameters.我对所有类型的参数都试过,两者都可以正常工作。 I decided eventually to adopt the factory constructor, because of the convenience of how the code is written, and readability, but it's a matter of choice and both will work fine in all the cases.我最终决定采用工厂构造函数,因为代码编写方式方便且可读性强,但这是一个选择问题,两者在所有情况下都可以正常工作。
One of the uses of factory constructor is, we can decide which instance to create, at run-time and move all the logic to the parent's factory constructor工厂构造函数的用途之一是,我们可以决定在运行时创建哪个实例并将所有逻辑移动到父级的工厂构造函数
let's say you have 1 parent class and 2 subclasses假设您有 1 个父类和 2 个子类
class GolderRetriever extends Dog{
GolderRetriever(String name):super(name);
}
class Labrador extends Dog{
Labrador(String name):super(name);
}
Then we have the parent class然后我们有父类
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);
}
}
}
and also I have enum DogType而且我有 enum DogType
enum DogType{
GOLDEN_RETRIEVER,DALMATION,UNKNOWN
}
Then in the main Method, you just delegate which subclass instance you want to create to the parent Dog class然后在主方法中,您只需将要创建的子类实例委托给父 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");
}
you can't do this with a named constructor as you can create only the instance of that class(Dog class), not its subtypes.您不能使用命名构造函数执行此操作,因为您只能创建该类(Dog 类)的实例,而不是其子类型。
Now the responsibility of which instance to create is delegated to the parent class.现在,创建哪个实例的责任委托给父类。 This can remove a lot of if-else boilerplate code.这可以删除很多 if-else 样板代码。 When you want to change the logic, you just change that in Animal class alone.当您想更改逻辑时,只需在 Animal 类中更改即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.