0x01 官方描述
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”关键字。例如,工厂构造函数可能会从缓存返回一个实例,或者可能会返回一个子类型的实例。
0x02 使用场景
避免创建过多的重复实例,如果该实例已创建,则直接从缓存获取。
调用子类的构造函数(工厂模式 factory pattern)
实现单例模式(singleton pattern)
0x03 Demo 创建缓存实例
引用自 https://dart.dev/guides/language/language-tour#factory-constructors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Logger { final String name; static final Map <String , Logger> _cache = <String , Logger>{}; factory Logger(String name) { return _cache.putIfAbsent(name, () => Logger._internal(name)); } Logger._internal(this .name) { print ('生成新实例:$name ' ); } } void main(List <String > args) { var p1 = Logger('1' ); var p2 = Logger('2' ); var p3 = Logger('1' ); print (identical(p1, p2)); print (identical(p1, p3)); }
调用子类的构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 abstract class Animal extends Object { String name; void getNoise(); factory Animal(String type, String name) { switch (type) { case 'cat' : return Cat(name); break ; case 'dog' : return Dog(name); break ; 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~' ); } } void main(List <String > args) { var cat = Animal('cat' , 'haha' ); var dog = Animal('dog' , 'hehe' ); cat.getNoise(); dog.getNoise(); }
实现单例模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Singleton { static final Singleton _singleton = Singleton._internal(); factory Singleton() { return _singleton; } Singleton._internal(); } void main(List <String > args) { var s1 = Singleton(); var s2 = Singleton(); print (identical(s1, s2)); }