关于这里提到的工厂构建器示例,我有一些棘手的问题(https://www.dartlang.org/guides/language/language-tour#factory-constructors). 我知道在基本级别上只有三种类型的构造函数-默认构造函数、命名构造函数和参数化构造函数.
关于这里提到的工厂构建器示例,我有一些棘手的问题(https://www.dartlang.org/guides/language/language-tour#factory-constructors). 我知道在基本级别上只有三种类型的构造函数-默认构造函数、命名构造函数和参数化构造函数.
tl;dr在您不希望necessarily返回类本身的new实例的情况下使用工厂.使用 case :
Explanation个
Dart类可能有generative constructors或factory constructors.个生成构造函数,它是一个总是返回类的新实例的函数.因此,它不使用return
关键字.常见的生成构造函数的形式如下:
class Person {
String name;
String country;
// unnamed generative constructor
Person(this.name, this.country);
}
var p = Person("...") // returns a new instance of the Person class
工厂构造器比生成构造器有更宽松的约束.工厂只需要返回一个与类类型相同或实现其方法(即满足其接口)的实例.这可能是类的新实例,但也可能是类的现有实例或子类的新/现有实例(必须与父类具有相同的方法).工厂可以使用控制流来确定要返回的对象,并且必须使用return
关键字.为了让工厂返回新的类实例,它必须首先调用生成构造函数.
在您的示例中,未命名的工厂构造函数首先读取名为_cache
的映射属性(因为它是Static
,所以存储在类级别,因此独立于任何实例变量).如果实例变量已经存在,则返回它.否则,通过调用命名的生成构造函数Logger._internal
生成新实例.该值将被缓存,然后返回.由于生成构造函数只接受name
参数,因此mute
属性将始终初始化为false,但可以使用默认setter进行更改:
var log = Logger("...");
log.mute = true;
log.log(...); // will not print
factory
一词暗指工厂模式,它是关于允许构造函数根据提供的参数返回子类实例(而不是类实例).Dart中这个用例的一个很好的例子是抽象HTML Element class,它定义了几十个返回不同子类的命名工厂构造函数.例如,Element.div()
和Element.li()
分别返回<div>
和<li>
个元素.
在这个缓存应用程序中,我发现"工厂"这个词有点用词不当,因为它的目的是避免调用生成性构造函数,而且我认为现实世界中的工厂本质上是生成性的.也许这里更合适的术语应该是"仓库":如果一件商品已经可以买到,就把它从货架上取下来,然后送货.如果没有,就叫一个新的.
所有这些与命名构造函数有何关系?生成构造函数和工厂构造函数都可以是未命名的,也可以是命名的:
...
// named generative
// delegates to the default generative constructor
Person.greek(String name) : this(name, "Greece");
// named factory
factory Person.greek(String name) {
return Greek(name);
}
}
class Greek extends Person {
Greek(String name) : super(name, "Greece");
}