一. 官方的描述
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 创建缓存实例
putIfAbsent的用法在文末[1]
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
-
putIfAbsent
如果存在[key],则会返回它的值。
如果不存在,就会调用后面的函数,生成新值,然后插入,并返回该值。
与update的ifAbsent不同的是,ifAbsent不会添加或修改数据。 ↩