我一直在用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值.

那么,这到底是一种糟糕的做法,还是在利用一项有用的功能呢?

推荐答案

从工厂返回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";
}

附注:

我个人认为,Dart中从factory返回nullbad practice,因为Dart中的工厂很难与建设者区分开来.

从外部看,它们看起来像构造函数,不同之处在于它们更强大,因为它们可以构造不同类型的对象.

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

Dart相关问答推荐

使用arm64v8/DART Docker映像进行编译时不支持DART镜像

dart run edge build cloudflare_workers --dev 命令在我的项目(笔记本电脑)中不起作用

polymer.dart 中的@observable 和@published 有什么区别?

如何在flutter中加载数据之前显示进度对话框?

寻找provider context 的flutter问题

NetworkImage 正在缓存旧图像

Asset图像作为Card背景,Flutter 中顶部有文本

Flutter:Firebase 基本查询或基本搜索代码

如何使用Flutter在按钮网格中滑动(swipe)/拖动(drag) 2 个或更多按钮

Flutter DatePicker 没有day选项

Flutter-创建value和name数组

有没有可能用Flatter摄像头插件播放视频?

在调试和生产模式之间切换

如何在 Dart 中监听自定义事件?

如何在 Dart 中使用 char 类型?

从 Dart Map 中删除选定的键

你如何在 Dart 中创建一个 Stream?

如何将 `ByteData` 实例写入 Dart 中的文件?

如何在 Dart 中连接两个字符串?

如何在 base64 中编码 Dart 字符串?