Constructor 在Dart中从工厂构造函数返回null是否可以接受?
我一直在用Dart写代码。我真的很喜欢工厂的建设者,但我担心我滥用了它的实用性。特别是,在编写值对象类时,如果验证失败,有时会返回nullConstructor 在Dart中从工厂构造函数返回null是否可以接受?,constructor,null,dart,factory,Constructor,Null,Dart,Factory,我一直在用Dart写代码。我真的很喜欢工厂的建设者,但我担心我滥用了它的实用性。特别是,在编写值对象类时,如果验证失败,有时会返回null 类电子邮件地址{ 静态最终RegExp_regex=newregexp(…); 最终字符串_值; 工厂电子邮件地址(字符串输入){ 返回_regex.hasMatch(输入)?新电子邮件地址。_internal(输入):null; } const EmailAddress.\u internal(此.\u值); toString()=>\u值; } 一开始
类电子邮件地址{
静态最终RegExp_regex=newregexp(…);
最终字符串_值;
工厂电子邮件地址(字符串输入){
返回_regex.hasMatch(输入)?新电子邮件地址。_internal(输入):null;
}
const EmailAddress.\u internal(此.\u值);
toString()=>\u值;
}
一开始,这似乎并没有那么糟糕。然而,当你实际使用它时,这就是你所看到的
创建电子邮件地址()的方法{
var emailAddress=新的电子邮件地址(“绝对不是电子邮件地址”);
...
}
<> P>为什么这是坏的,是来自另一种静态类型语言的开发人员,如java或C++,会期望<代码>电子邮件地址< /COD>总是被初始化为非空值。这完全可以接受的理由是构造函数是工厂,因此允许返回null
值
那么,这是错误的做法还是利用了有用的功能?从工厂返回
null
值是可以接受的,因为Dart中的内置工厂
功能没有任何空限制
另一方面,我可以重新表述您的问题“从相等运算符返回null是否可以接受”
bool运算符==(其他){
返回null;
}
这也是可以接受的,因为不存在此运算符不能返回null
值的限制
但还有一个问题?为什么要这样做?如何避免
工厂电子邮件地址(字符串输入){
返回\u regex.hasMatch(输入)?新电子邮件地址。\u内部(输入):
抛出“出了问题”;
}
附言
我个人认为,在Dart中从工厂返回null
是一种糟糕的做法,因为Dart中的工厂很难与构造函数区分开来
从外部看,它们看起来像构造函数,不同之处在于它们更强大,因为它们可以构造不同类型的对象
他们也有自己的限制,但这是另一回事。这是不好的做法。当有人调用构造函数时,他们希望得到一个非空值
对于您的情况,我可以使用静态方法进行验证:
类电子邮件地址{
最终字符串_值;
静态最终RegExp_regex=新RegExp(r“…”);
静态bool isValid(字符串电子邮件)=>\u regex.hasMatch(电子邮件);
电子邮件地址(此值){
如果(!isValid(_value))抛出“无效电子邮件:$_value”;
}
}
现在您可以获得代码重用和良好的语义。例如:
querySelector(#sendButton”)。已禁用=!EmailAddress.isValid(用户电子邮件);
请不要这样做。作为构造函数的用户,我希望收到构造函数类的实例。可以在Dart中返回预先存在的实例或子类型的实例,但不要返回null
在这里,我推荐两个选项中的一个来完成您想要的操作:
对无效输入引发异常。这样,如果您将null
存储在某个地方,那么至少错误出现的时间是早的,而不是晚的
使用静态方法而不是构造函数。静态方法可以返回null
,并且不会造成混淆
提供回退路径,例如int.parse
does。您可以接受将在发生错误时调用的回调
我自己喜欢1号或3号。我想明确地知道什么时候某些东西是无效的。我不同意其他答案:至少对于命名的工厂
构造函数,我认为返回null
没有任何错误
工厂
构造函数可以与新
一起使用,并且可以是未命名的默认构造函数,因此,在大多数情况下,命名的工厂
构造函数无法与调用站点上的静态
方法调用区分开来
我没有看到返回null
的static
方法有任何错误,因此我也没有看到返回null
的命名工厂构造函数有任何错误
如果工厂
构造函数未命名,那么我同意调用方可能会意外地返回null
,可能应该避免返回
也就是说,在这种情况下,没有太多的理由使用工厂
构造函数而不是静态
方法,而静态
方法更清晰
更新
使用static
方法返回null
是迁移到null安全的代码的建议。请参阅。使用空安全省道,工厂
构造函数不再允许返回null
.返回\u regex.hasMatch(输入)?新电子邮件地址。_内部(输入):抛出“出错”代码>此外,如果您希望错误传递的参数得到正确的结果,则“希望emailAddress始终初始化为非空值”并不总是可能的。电子邮件地址的验证不是在构造函数中完成的,而是在您向用户请求时完成的。尽快验证,并尽快通知用户(例如,在这种情况下禁用“发送”按钮)是最佳做法。我同意您在这方面的意见。我正在考虑类似于var-emailAddress=new-emailAddress.fromString(输入)代码>。我认为这是一个更清楚的事实,这实际上是一个工厂构造函数,返回值可以是空的。即使对于命名构造函数,我也会认为这是反模式。当我用new
调用构造函数时,我并不期望<