title: dart中factory关键词的使用
date: 2020-05-10 13:26:43
tags: 学习
一. 官方的描述
Use the factory keyword when implementing a constructor that doesn’t always create a new instance of its class. For example, a factory constructor might return an instance from a cache, or it might return an instance of a subtype.
当你使用factory关键词时,你能控制在使用构造函数时,并不总是创建一个新的该类的对象,比如它可能会从缓存中返回一个已有的实例,或者是返回子类的实例。
二. 与构造函数的差别
构造函数不能有返回值,而factory必须有
三. 3个使用场景
-
A factory constructor can check if it has a prepared reusable instance in an internal cache and return this instance or otherwise create a new one.
避免创建过多的重复实例,如果已创建该实例,则从缓存中拿出来。 -
You can for example have an abstract class A (which can't be instantiated) with a factory constructor that returns an instance of a concrete subclass of A depending for example on the arguments passed to the factory constructor.
调用子类的构造函数(工厂模式 factory pattern) -
singleton pattern
实现单例模式
四. 3个demo(初学dart,欢迎大家指正)
demo-1 创建缓存实例
(援引https://dart.dev/guides/language/language-tour#factory-constructors)
putIfAbsent的用法在文末
class Logger {
final String name;
// 缓存已创建的对象
static final Map<String, Logger> _cache = <String, Logger>{};
factory Logger(String name) {
// 不理解putIfAbsent可以查看文末的简述
return _cache.putIfAbsent(
name, () => Logger._internal(name));
}
// 私有的构造函数
Logger._internal(this.name){
print("生成新实例:$name");
}
}
// 测试
main() {
var p1 = new Logger("1");
var p2 = new Logger('22');
var p3 = new Logger('1');// 相同对象直接访问缓存
//identical会对两个对象的地址进行比较,相同返回true,
//等同于 == ,好处是如果重写了==,那用identical 会更方便。
print(identical(p1,p3));
}
> 生成新实例:1
> 生成新实例:2
> true
demo-2 调用子类的构造函数(工厂模式 factory pattern)
我还没感受到这种模式的优势..
abstract class Animal {
String name;
void getNoise();
factory Animal(String type,String name) {
switch(type) {
case "cat":
return new Cat(name);
case "dog":
return new Dog(name);
default:
throw "The '$type' is not an animal";
}
}
}
class Cat implements Animal {
String name;
Cat(this.name);
@override
void getNoise() {
print("${this.name}: mew~");
}
}
class Dog implements Animal {
String name;
Dog(this.name);
@override
void getNoise() {
print("${this.name}: wang~");
}
}
int main(){
var cat = new Animal("cat","wiki");
var dog = new Animal("dog","baobao");
cat.getNoise();
dog.getNoise();
return 0;
}
> wiki: mew~
> baobao: wang~
demo-3 单例模式(singleton pattern)
class Singleton {
static final Singleton _singleton = Singleton._internal();
factory Singleton() {
return _singleton;
}
Singleton._internal();
}
main() {
var s1 = Singleton();
var s2 = Singleton();
print(identical(s1, s2));
}
> true