从Dart中的工厂构造函数返回null是否可以接受?

时间:2014-02-15 02:04:11

标签: constructor null dart factory

我一直在Dart写一些代码。我真的很喜欢工厂的构造函数,但我担心我会滥用它的用处。特别是,当我编写一个值对象类时,如果验证失败,我有时会返回null。

class EmailAddress {
  static final RegExp _regex = new RegExp(...);
  final String _value;

  factory EmailAddress(String input) {
    return _regex.hasMatch(input) ? new EmailAddress._internal(input) : null;
  }

  const EmailAddress._internal(this._value);

  toString() => _value;
}

起初,这似乎并不那么糟糕。但是,当你真正使用它时,这就是你所看到的。

methodThatCreatesAnEmailAddress() {
  var emailAddress = new EmailAddress("definitely not an email address");
  ...
}

为什么这是不好的论点是来自另一种静态类型语言(如Java或C ++)的开发人员希望emailAddress始终初始化为非空值。为什么这是完全可以接受的论点是构造函数是工厂的,因此允许返回null值。

这是一种不好的做法还是利用了一个有用的功能?

5 个答案:

答案 0 :(得分:2)

从工厂返回null值是可以接受的,因为Dart Factory software concept中的内置factory功能没有任何空值限制。

另一方面,我可以改写你的问题“从等于运算符返回null是否可以接受”

bool operator ==(other) {
  return null;
}

这也是可以接受的,因为没有这样的限制,这个操作符不能返回null值。

但还有另外一个问题?为什么要这样做以及如何避免它?

factory EmailAddress(String input) {
  return _regex.hasMatch(input) ? new EmailAddress._internal(input) :
    throw "something went wrong";
}

P.S。

我个人认为在Dart中从null返回factorybad practice,因为Dart中的工厂很难与指导者区分开来。

从外面看,它们看起来像是构造函数,区别在于它们更强大,因为它可以构造不同类型的对象。

他们也有他们的限制,但这是另一个故事......

答案 1 :(得分:2)

这是不好的做法。当有人调用构造函数时,他们期望一个非空值。

对于你的情况,我可以用静态方法进行验证:

class EmailAddress {
  final String _value;
  static final RegExp _regex = new RegExp(r"...");

  static bool isValid(String email) => _regex.hasMatch(email);

  EmailAddress(this._value) {
    if (!isValid(_value)) throw "Invalid email: $_value";
  }
}

现在您可以获得代码重用和良好的语义。例如:

querySelector("#sendButton").disabled = !EmailAddress.isValid(userEmail);

答案 2 :(得分:2)

请不要这样做。作为构造函数的用户,我希望收到构造函数类的实例。可以在Dart中返回预先存在的实例或子类型的实例,但不要返回null

我建议你在这里做两件事之一:

  1. 在无效输入上抛出异常。这样至少错误是早期的,而不是以后如果你已经存储了null某处。

  2. 使用静态方法而不是构造函数。静态方法可以返回null而不会令人困惑。

  3. 提供后备路径,例如int.parse。您可以接受将在错误时调用的回调。

  4. 我自己更喜欢1或3。当某些事情无效时,我想明确知道。

答案 3 :(得分:2)

使用空安全 Dart,不再允许 factory 构造函数返回 null

Existing factory constructors that return null are expected to be replaced with static methods when migrated

答案 4 :(得分:1)

我将不同意其他答案:至少对于命名为 factory的构造函数,返回null不会有什么问题。

The main differences between a factory constructor and a static methodfactory的构造函数可以与new一起使用,并且可以是未命名的默认构造函数。 Using new is now discouraged,因此命名的factory构造函数与呼叫站点的static方法调用是无法区分的。

我没有看到返回static的{​​{1}}方法有什么问题,因此我也没有看到返回null的命名factory构造函数的任何问题

如果null构造函数是未命名,那么我同意调用者返回factory可能是意外的,应该避免。