本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
工厂函数(Factory Constructor)是Dart语言中的一种特殊的构造函数,用于控制对象的创建过程。它不是一个真正的构造函数,而是一个返回对象实例的静态方法。
class MyClass {
// 普通构造函数
MyClass();
// 工厂构造函数
factory MyClass.factory() {
return MyClass();
}
}
工厂函数 vs 普通构造函数
| 返回类型 | 总是返回当前类的新实例 | 可以返回任意类型(通常是当前类或其子类) |
| this访问 | 可以访问this | 不能访问this(因为是静态的) |
| 创建方式 | 总是创建新实例 | 可以重用现有实例(如单例) |
| super调用 | 可以调用super | 不能调用super |
| 初始化列表 | 支持初始化列表 | 不支持初始化列表 |
二、代码示例
2.1 单例模式(最常用)
class Singleton {
// 私有静态实例
static Singleton? _instance;
// 私有命名构造函数
Singleton._internal() {
print('内部构造函数被调用');
}
// 工厂构造函数
factory Singleton() {
// 如果实例不存在,创建新实例
_instance ??= Singleton._internal();
return _instance!;
}
void doSomething() {
print('单例方法被调用');
}
}
// 使用示例
void main() {
var s1 = Singleton();
var s2 = Singleton();
print(identical(s1, s2)); // 输出: true(是同一个对象)
}
2.2 根据参数返回不同类型的对象
abstract class Animal {
String makeSound();
// 工厂构造函数
factory Animal(String type) {
switch (type) {
case 'dog':
return Dog();
case 'cat':
return Cat();
case 'cow':
return Cow();
default:
throw ArgumentError('未知的动物类型: $type');
}
}
}
class Dog implements Animal {
@override
String makeSound() => '汪汪汪';
}
class Cat implements Animal {
@override
String makeSound() => '喵喵喵';
}
class Cow implements Animal {
@override
String makeSound() => '哞哞哞';
}
// 使用示例
void main() {
Animal dog = Animal('dog');
print(dog.makeSound()); // 输出: 汪汪汪
Animal cat = Animal('cat');
print(cat.makeSound()); // 输出: 喵喵喵
}
2.3 反序列化/从JSON创建对象
class User {
final String id;
final String name;
final int age;
// 私有主构造函数
User._({required this.id, required this.name, required this.age});
// 工厂构造函数 – JSON反序列化
factory User.fromJson(Map<String, dynamic> json) {
// 数据验证和转换
if (json['id'] == null || json['name'] == null) {
throw FormatException('JSON数据不完整');
}
return User._(
id: json['id'].toString(),
name: json['name'],
age: json['age'] ?? 0, // 提供默认值
);
}
// 转换为JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'age': age,
};
}
}
// 使用示例
void main() {
var json = {'id': '123', 'name': '张三', 'age': 25};
var user = User.fromJson(json);
print(user.name); // 输出: 张三
var userJson = user.toJson();
print(userJson); // 输出: {id: 123, name: 张三, age: 25}
}
三、工厂函数的实现原理
3.1 编译后的代码分析
// 源代码
class Example {
static Example? _cache;
factory Example() {
_cache ??= Example._internal();
return _cache!;
}
Example._internal();
}
// 编译器处理后的大致等价代码
class Example {
static Example? _cache;
// 工厂构造函数被转换为静态方法
static Example _factory_constructor() {
_cache ??= Example._internal();
return _cache!;
}
Example._internal();
// 外部调用实际上调用的是静态方法
// 当我们写 Example() 时,实际上调用的是 _factory_constructor()
}



