参考文档 :

在这里插入图片描述





一、单例模式核心规则



Dart 单例模式 统一 核心规则 :

  • 私有构造 : Student._internal() → 禁止外部 new , 这是一个 私有 的 命名构造函数 , 外部不能实例化 → 保证全局只有一个单例 ;
  • 静态实例 : 类内部保存唯一 " 私有 , 静态 " 对象 ;
  • 对外暴露 : 通过 instance 或 factory 提供获取方式 ;
  • 验证单例 : identical(实例1, 实例2) == true

单例模式 首选 饿汉式 , 简单、安全、Flutter 官方 / 大厂都在用 ;





二、饿汉式单例 ( 最推荐、企业首选 )




1、饿汉式单例简介


饿汉式单例 ( 最推荐、企业首选 ) 在 类加载时 就创建实例 , 安全、简单、无坑 ;

代码示例 :

class Student {
  // 私有命名构造函数 ( 固定要求 ) 
  Student._internal();

  // 静态单例实例 ( 饿汉式 ) 
  static final Student instance = Student._internal();

  // 测试方法
  void study() {
    print("学生学习中");
  }
}

使用方法 :

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、懒汉式单例简介


懒汉式单例 , 延迟初始化 , 第一次调用时才创建实例 ;

不用时不创建 , 用到时才创建 ; 节省资源 ;

代码示例 :

class Student {
  // 私有命名构造函数 ( 固定要求 ) 
  Student._internal();

  // 私有静态变量
  static Student? _instance;

  // 公有 getter 获取单例
  static Student get instance {
    _instance ??= Student._internal();
    return _instance!;
  }

  void study() {
    print("学生学习中");
  }
}

使用方法 :

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 instanceGetter 访问器 , Dart 类的 get 方法 , 不用括号调用 ;

其作用是 提供 对外提供获取单例的统一入口 ;


Getter 访问器 标准语法 : 没有参数 , 调用时不用写 () 括号 , 本质是方法 , 但用起来像属性 , 可以写逻辑 ( 判断、计算 ) ;

返回类型 get 名称 {
  return 要返回的值;
}

简写语法 :

返回类型 get 名称 => 要返回的值;

5、空赋值运算符


_instance ??= Student._internal(); 中的 ??= 是 空赋值运算符 ,

变量 ??= 值 表示 变量为 null 时才赋值 , 否则不操作 ;

这是 懒汉式单例 的 核心 , 第一次调用才创建实例 , 之后直接返回单例对象 ;


6、空安全断言符


return _instance!; 中的 !空安全断言符 , 作用是 把可空对象转为非空 , 安全返回 ;

变量! → 告诉编译器 " 此变量一定不为空 " ;





四、极简空安全 懒汉式单例




1、极简空安全 懒汉式 单例简介


极简空安全 懒汉式单例 是 Dart 空安全最简洁写法 ;

代码示例 :

class Student {
  Student._internal();

  static Student? _instance;
  static Student get instance => _instance ??= Student._internal();

  void study() {
    print("学生学习中");
  }
}

使用方法 :

void main() {
  final student = Student.instance;
  student.study();
}

2、箭头函数


只是 将 普通 懒汉式 单例 的 Getter 方法 ,

  // 公有 getter 获取单例
  static Student get instance {
    _instance ??= Student._internal();
    return _instance!;
  }

简化为了如下写法 :

static Student get instance => _instance ??= Student._internal();




五、工厂构造函数单例




1、工厂构造函数单例 简介


这是在 饿汉式 单例模式 基础上 , 增加了一个 工厂构造函数 ;

工厂构造函数单例 的 调用最优雅 , 外部像普通类一样 Student() , 内部是单例 ;

代码示例 :

class Student {
  Student._internal();

  static final Student _instance = Student._internal();

  // 工厂构造
  factory Student() {
    return _instance;
  }

  void study() {
    print("学生学习中");
  }
}

使用方法 :

void main() {
  // 像普通类一样调用 , 但永远是同一个单例
  final s1 = Student();
  final s2 = Student();

  print(identical(s1, s2)); // true
}

2、factory 工厂构造函数


下面的代码是 工厂构造函数 , 不自动生成新对象 , 可自由返回对象 , 其作用是 让外部 Student() 函数 拿到的永远是同一个单例 ;

  // 工厂构造
  factory Student() {
    return _instance;
  }

更多推荐