Flutter单例模式管理插件singlet的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter单例模式管理插件singlet的使用

singlet logo

A Dart package that provides macros to help you avoid feeling like you’re wearing the same old code over and over again. This package offers a simple way to create singleton classes, ensuring you always have just one instance when you need it. Because sometimes, one is really all you need.

特性

  • 轻松创建单例类,使用[@Singleton](/user/Singleton)宏。
  • 可以自定义实例字段名称,使用@SingletonNamed宏。
  • 通过强制执行单一实例模式,保持你的代码库DRY(Don’t Repeat Yourself)。

开始使用

要开始使用singlet,将其添加到你的pubspec.yaml文件中:

dependencies:
  singlet: ^latest_version
  macros: ^latest_macros_version

然后运行以下命令来安装包:

flutter pub get

重要提示:此包使用Dart宏,这是一个实验性的功能。要使用此包,你需要在项目中启用宏。

启用宏

  1. analysis_options.yaml文件中添加以下内容:

    analyzer:
      enable-experiment:
        - macros
    
  2. 运行时启用宏:

    dart run --enable-experiment=macros your_app.dart
    flutter run --enable-experiment=macros
    

使用方法

要创建一个单例类,只需使用[@Singleton](/user/Singleton)()宏标注你的类:

import 'package:singlet/singlet.dart';

[@Singleton](/user/Singleton)()
class MyService {
  void doSomething() {
    print("Doing something unique.");
  }
}

void main() {
  final service1 = MyService.instance;
  final service2 = MyService.instance;
  print(identical(service1, service2)); // 输出: true
}

如果你需要自定义实例名称,可以使用@SingletonNamed()宏:

import 'package:singlet/singlet.dart';

@SingletonNamed('uniqueInstance')
class AnotherService {
  void doSomethingElse() {
    print("Doing something else, uniquely.");
  }
}

void main() {
  final service1 = AnotherService.uniqueInstance;
  final service2 = AnotherService.uniqueInstance;
  print(identical(service1, service2)); // 输出: true
}

完整示例

以下是一个完整的示例,展示了如何使用singlet创建单例类:

import 'package:singlet/singlet.dart';

// 创建一个单例类
[@Singleton](/user/Singleton)()
class MyService {
  void doSomething() {
    print("Doing something unique.");
  }
}

// 主函数
void main() {
  // 获取单例实例
  final service1 = MyService.instance;
  final service2 = MyService.instance;

  // 检查两个实例是否相同
  print(identical(service1, service2)); // 输出: true

  // 执行操作
  service1.doSomething();
}

更多关于Flutter单例模式管理插件singlet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter单例模式管理插件singlet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,使用单例模式管理插件状态或配置是一种常见的设计模式。singlet 这个词可能是一个泛指或者是一个特定库的简化名称,但在Flutter的官方生态系统中,并没有一个叫做 singlet 的插件。不过,我们可以通过实现单例模式来达到类似的效果。

下面是一个如何在Flutter中使用单例模式管理插件或全局状态的代码示例。这里我们以一个简单的全局配置管理为例:

1. 创建一个单例类

首先,我们创建一个单例类来管理全局配置。

class ConfigManager {
  // 私有静态实例,用于实现单例模式
  private static ConfigManager? _instance;

  // 私有构造函数,防止外部实例化
  private ConfigManager() {
    // 可以在这里初始化一些默认配置
  }

  // 公共静态方法,用于获取单例实例
  static ConfigManager getInstance() {
    if (_instance == null) {
      _instance = ConfigManager();
    }
    return _instance!;
  }

  // 配置属性示例
  String apiUrl = "https://api.example.com";

  // 提供配置修改的方法
  void setApiUrl(String url) {
    apiUrl = url;
  }

  // 提供配置获取的方法
  String getApiUrl() {
    return apiUrl;
  }
}

2. 在需要使用配置的地方获取单例实例

接下来,我们可以在任何需要使用 ConfigManager 的地方通过 ConfigManager.getInstance() 来获取配置。

import 'package:flutter/material.dart';
import 'config_manager.dart'; // 假设上面的类定义在这个文件中

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 获取单例实例并读取配置
    final config = ConfigManager.getInstance();
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page', apiUrl: config.getApiUrl()),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title, required this.apiUrl}) : super(key: key);

  final String title;
  final String apiUrl;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _changeApiUrl() {
    // 获取单例实例并修改配置
    final config = ConfigManager.getInstance();
    config.setApiUrl("https://newapi.example.com");

    // 更新UI(如果需要的话,这里可以通过setState来刷新UI)
    // 但在这个例子中,由于我们直接在单例对象中修改,所以不需要刷新UI来显示新配置
    // 如果需要在UI中即时反映变化,可以考虑使用Provider、Riverpod等状态管理库
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current API URL: ${widget.apiUrl}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _changeApiUrl,
              child: Text('Change API URL'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 线程安全:如果你的应用是多线程的(比如在原生平台插件中),需要确保单例的访问是线程安全的。
  2. 状态管理:对于更复杂的全局状态管理,可以考虑使用Flutter的官方或社区提供的状态管理库,如Provider、Riverpod、MobX等。
  3. 持久化:如果配置需要在应用重启后仍然保留,可以考虑将配置保存到本地存储(如SharedPreferences)。

这个示例展示了如何在Flutter中使用单例模式来管理全局配置。根据你的具体需求,你可以扩展这个模式来管理更多的全局状态或插件配置。

回到顶部