# 工厂函数 factory

本文作者:阳九五 (opens new window)

本站地址:https://blog.56321654.xyz (opens new window)

使用 factory 关键字标识类的构造函数将会令该构造函数变为工厂构造函数

当你使用 factory 关键词时,你能控制在使用构造函数时,并不总是创建一个新的该类的对象,比如它可能会从缓存中返回一个已有的实例,或者是返回子类的实例。

  • 工厂构造函数不需要每次构建新的实例,且不会自动生成实例,而是通过代码来决定返回的实例对象
  • 工厂构造函数类似于 static 静态成员,无法访问 this 指针

# 减少重复实例对象

避免创建过多的重复实例,如果已创建该实例,则从缓存中拿出来。

class Phone {
    int _number;
    Phone(this._number);

    factory Phone.fromJson(Map<String, dynamic> json) =>
        Phone(json['number'] as int);

    // 如果不用工厂函数,就要用类静态方法,这样会有多余的实例对象
    // static fromJson(Map<String, dynamic> json) =>
    //     Phone(json['number'] as int);
        
    void call() {
        print('Calling $_number...');
    }
    }

    void main() {
    var p = Phone.fromJson({"number": 911});
    p.call();
}

Calling 911...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

如果不用工厂函数,就要用类静态方法,这样会有多余的实例对象

# 单例模式

单例模式是一种确保一个类只有一个实例,并提供一个全局访问点来获取这个实例的设计模式。

  • Dart 的单例模式实现通常使用私有构造函数和工厂构造函数。
  • 单例模式确保了全局只有一个实例,但也要谨慎使用,因为它可能会导致代码难以测试和维护。
  • 在多线程环境中,需要额外的同步机制来确保线程安全。

# 懒汉式单例(Lazy Singleton)

这种模式下,实例在第一次被需要时创建。

class Singleton {
  static Singleton? _instance;

  Singleton._internal() {}

  factory Singleton() {
    _instance ??= Singleton._internal();
    return _instance!;
  }
}

void main() {
    var p1 = Singleton();
    var p2 = Singleton();
    print(identical(p1, p2));
}

true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 饿汉式单例(Eager Singleton)

这种模式下,实例在类加载时立即创建。

class Singleton {
  static final Singleton _instance = Singleton._internal();

  Singleton._internal();

  factory Singleton() {
    return _instance;
  }
}

void main() {
    var p1 = Singleton();
    var p2 = Singleton();
    print(identical(p1, p2));
}

true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 单例模式与全局访问点

有时候,我们希望有一个全局的访问点来获取单例实例

class Singleton {
  static final Singleton _instance = Singleton._internal();

  Singleton._internal();

  factory Singleton() {
    return _instance;
  }

  static final Singleton instance = Singleton();
}

void main() {
    var p1 = Singleton();
    var p2 = Singleton();
    print(identical(p1, p2));
    print(identical(p1, Singleton.instance));
}

true
true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 调用子类

调用子类的构造函数,这是一种常见的设计模式. 可以让抽象类同时可被实例化

abstract class Phone{
    void call();

    // factory定义工厂函数
    factory Phone(String type){
        switch (type){
            case "android":
                return Android();
            case "ios":
                return Ios();
            default:
                throw "The '$type' is not an animal";
        }
    }
}

class Android implements Phone{
    
    void call(){
        print('Android Calling...');
    }
}

class Ios implements Phone{
    
    void call(){
        print('Ios Calling...');
    }
}

// 工厂构造函数不需要每次构建新的实例,且不会自动生成实例,而是通过代码来决定返回的实例对象
// 工厂构造函数类似于 static 静态成员,无法访问 this 指针
void main(List<String> args) {
    var android = Phone('android');
    var ios = Phone('ios');
    android.call();
    ios.call();
}

Android Calling...
Ios Calling...
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
最近更新: 8/6/2025, 2:39:35 PM