文章目录
- 一、单例模式核心规则
- 二、饿汉式单例 ( 最推荐、企业首选 )
- 三、懒汉式单例
-
- 1、懒汉式单例简介
- 2、私有命名构造函数
- 3、私有静态变量
- [4、Getter 访问器](#4、Getter 访问器)
- 5、空赋值运算符
- 6、空安全断言符
- [四、极简空安全 懒汉式单例](#四、极简空安全 懒汉式单例)
-
- [1、极简空安全 懒汉式 单例简介](#1、极简空安全 懒汉式 单例简介)
- 2、箭头函数
- 五、工厂构造函数单例
-
- [1、工厂构造函数单例 简介](#1、工厂构造函数单例 简介)
- [2、factory 工厂构造函数](#2、factory 工厂构造函数)
参考文档 :
- Flutter 官方文档 : https://docs.flutter.dev/install/quick
- 使用出现网络问题 , 参考 在中国网络环境下使用 Flutter 文档 ;

一、单例模式核心规则
Dart 单例模式 统一 核心规则 :
- 私有构造 : Student._internal() → 禁止外部 new , 这是一个 私有 的 命名构造函数 , 外部不能实例化 → 保证全局只有一个单例 ;
- 静态实例 : 类内部保存唯一 " 私有 , 静态 " 对象 ;
- 对外暴露 : 通过 instance 或 factory 提供获取方式 ;
- 验证单例 :
identical(实例1, 实例2) == true
单例模式 首选 饿汉式 , 简单、安全、Flutter 官方 / 大厂都在用 ;
二、饿汉式单例 ( 最推荐、企业首选 )
1、饿汉式单例简介
饿汉式单例 ( 最推荐、企业首选 ) 在 类加载时 就创建实例 , 安全、简单、无坑 ;
代码示例 :
dart
class Student {
// 私有命名构造函数 ( 固定要求 )
Student._internal();
// 静态单例实例 ( 饿汉式 )
static final Student instance = Student._internal();
// 测试方法
void study() {
print("学生学习中");
}
}
使用方法 :
dart
void main() {
// 获取单例
final s1 = Student.instance;
final s2 = Student.instance;
// 判断是否是同一个对象 ( true = 单例成功 )
print(identical(s1, s2)); // true
// 调用方法
s1.study();
}
2、私有命名构造函数
Student._internal(); 是 私有命名构造函数 ;
Dart 中以下划线 _ 开头的成员 → 私有 ( 只有当前类内部能访问 ) ;
_internal 是构造函数的名字 ( 自定义名称 , 行业标准写法 ) , 默认都写 internal , 也可以是其它 任意函数名字 ;
私有命名构造函数 的 作用 是 禁止外部创建对象 , 外部无法实例化 , 从根源保证单例 ;
3、静态最终常量对象
static final Student instance = Student._internal(); 是单例的核心代码 , 包含 4 个 Dart 关键知识点:
- ①
static静态 : 静态成员属于类本身 , 不属于任何对象 ;- 全局只有一份 , 全局共享 ;
- 调用方式:Student.instance , 不需要创建对象 ;
- ②
final最终常量 : final 赋值后不能再修改 , 保证 instance 永远指向第一次创建的那个对象 , 彻底保证唯一、不可替换 ; - ③
Student类型 : 表示这个静态变量存储的是 Student 类的实例对象 ; - ④
= Student._internal();表示 在 类加载时就自动创建单例 ( 饿汉式特点 ) ; 直接调用私有构造 , 创建唯一实例 ;
三、懒汉式单例
1、懒汉式单例简介
懒汉式单例 , 延迟初始化 , 第一次调用时才创建实例 ;
不用时不创建 , 用到时才创建 ; 节省资源 ;
代码示例 :
dart
class Student {
// 私有命名构造函数 ( 固定要求 )
Student._internal();
// 私有静态变量
static Student? _instance;
// 公有 getter 获取单例
static Student get instance {
_instance ??= Student._internal();
return _instance!;
}
void study() {
print("学生学习中");
}
}
使用方法 :
dart
void main() {
final s1 = Student.instance;
final s2 = Student.instance;
print(identical(s1, s2)); // true
s2.study();
}
2、私有命名构造函数
Student._internal(); 是 私有命名构造函数 , 其作用是 禁止外部 new Student() 创建对象 , 保证单例唯一性 ;
Dart 中下划线开头的方法 / 变量 = 私有 , 仅类内部可访问 ;
_internal 是单例标准命名 , 也可以使用其它命名 ;
3、私有静态变量
static Student? _instance; 是 静态私有变量 , 其作用是 内部存储单例对象 , 外部无法直接修改 ;
static:属于类 , 全局唯一一份 ;?:Dart 空安全 , 可空类型 ;
4、Getter 访问器
static Student get instance 是 Getter 访问器 , Dart 类的 get 方法 , 不用括号调用 ;
其作用是 提供 对外提供获取单例的统一入口 ;
Getter 访问器 标准语法 : 没有参数 , 调用时不用写 () 括号 , 本质是方法 , 但用起来像属性 , 可以写逻辑 ( 判断、计算 ) ;
dart
返回类型 get 名称 {
return 要返回的值;
}
简写语法 :
dart
返回类型 get 名称 => 要返回的值;
5、空赋值运算符
_instance ??= Student._internal(); 中的 ??= 是 空赋值运算符 ,
变量 ??= 值 表示 变量为 null 时才赋值 , 否则不操作 ;
这是 懒汉式单例 的 核心 , 第一次调用才创建实例 , 之后直接返回单例对象 ;
6、空安全断言符
return _instance!; 中的 ! 是 空安全断言符 , 作用是 把可空对象转为非空 , 安全返回 ;
变量! → 告诉编译器 " 此变量一定不为空 " ;
四、极简空安全 懒汉式单例
1、极简空安全 懒汉式 单例简介
极简空安全 懒汉式单例 是 Dart 空安全最简洁写法 ;
代码示例 :
dart
class Student {
Student._internal();
static Student? _instance;
static Student get instance => _instance ??= Student._internal();
void study() {
print("学生学习中");
}
}
使用方法 :
dart
void main() {
final student = Student.instance;
student.study();
}
2、箭头函数
只是 将 普通 懒汉式 单例 的 Getter 方法 ,
dart
// 公有 getter 获取单例
static Student get instance {
_instance ??= Student._internal();
return _instance!;
}
简化为了如下写法 :
dart
static Student get instance => _instance ??= Student._internal();
五、工厂构造函数单例
1、工厂构造函数单例 简介
这是在 饿汉式 单例模式 基础上 , 增加了一个 工厂构造函数 ;
工厂构造函数单例 的 调用最优雅 , 外部像普通类一样 Student() , 内部是单例 ;
代码示例 :
dart
class Student {
Student._internal();
static final Student _instance = Student._internal();
// 工厂构造
factory Student() {
return _instance;
}
void study() {
print("学生学习中");
}
}
使用方法 :
dart
void main() {
// 像普通类一样调用 , 但永远是同一个单例
final s1 = Student();
final s2 = Student();
print(identical(s1, s2)); // true
}
2、factory 工厂构造函数
下面的代码是 工厂构造函数 , 不自动生成新对象 , 可自由返回对象 , 其作用是 让外部 Student() 函数 拿到的永远是同一个单例 ;
dart
// 工厂构造
factory Student() {
return _instance;
}