Dart中多个系统封装的多用户单例管理实例

泛型单例管理器

import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

/// 泛型单例管理器
/// 用于管理不同类型用户模型的本地存储和更新
///
/// 使用示例:
/// ```dart
/// class UserModel {
///   final String id;
///   final String name;
///
///   UserModel({required this.id, required this.name});
///
///   factory UserModel.fromJson(Map<String, dynamic> json) {
///     return UserModel(
///       id: json['id'] as String,
///       name: json['name'] as String,
///     );
///   }
///
///   Map<String, dynamic> toJson() {
///     return {'id': id, 'name': name};
///   }
/// }
///
/// // 使用
/// final manager = SingleUserManager<UserModel>(
///   storageKey: 'user_manager',
///   fromJson: (json) => UserModel.fromJson(json),
/// );
///
/// // 初始化
/// await manager.initFromLocal();
///
/// // 更新
/// await manager.update(UserModel(id: '1', name: 'New Name'));
///
/// // 保存
/// await manager.save();
///
/// // 获取当前数据
/// final user = manager.current;
/// ```
class SingleUserManager<T> {
  /// 单例实例映射,使用类型字符串作为 key
  static final Map<String, SingleUserManager> _instances = {};

  /// 存储键名
  final String storageKey;

  /// 从 JSON 创建实例的函数
  final T Function(Map<String, dynamic>) fromJson;

  /// SharedPreferences 实例
  SharedPreferences? _prefs;

  /// 当前存储的数据
  T? _currentData;

  /// 是否已初始化
  bool _isInitialized = false;

  /// 私有构造函数
  SingleUserManager._internal({
    required this.storageKey,
    required this.fromJson,
  });

  /// 获取单例实例
  /// [storageKey] 存储键名,用于区分不同的管理器实例
  /// [fromJson] 从 JSON 创建实例的函数
  factory SingleUserManager({
    required String storageKey,
    required T Function(Map<String, dynamic>) fromJson,
  }) {
    final key = '$T$storageKey';
    return _instances.putIfAbsent(
          key,
          () => SingleUserManager._internal(
            storageKey: storageKey,
            fromJson: fromJson,
          ),
        )
        as SingleUserManager<T>;
  }

  /// 获取当前存储的数据
  T? get current => _currentData;

  /// 检查是否已初始化
  bool get isInitialized => _isInitialized;

  /// 检查是否有数据
  bool get hasData => _currentData != null;

  /// 从本地存储初始化数据
  /// 返回 true 表示成功加载数据,false 表示没有本地数据
  Future<bool> initFromLocal() async {
    try {
      _prefs ??= await SharedPreferences.getInstance();
      final jsonString = _prefs?.getString(storageKey);
      if (jsonString != null && jsonString.isNotEmpty) {
        final json = jsonDecode(jsonString) as Map<String, dynamic>;
        _currentData = fromJson(json);
        _isInitialized = true;
        return true;
      }
      _isInitialized = true;
      return false;
    } catch (e) {
      print('从本地初始化失败 ($storageKey): $e');
      _isInitialized = true;
      _currentData = null;
      return false;
    }
  }

  /// 更新当前数据
  /// [data] 新的数据对象
  Future<void> update(T data) async {
    _currentData = data;
  }

  /// 保存当前数据到本地存储
  /// 如果当前没有数据,则不会执行保存操作
  Future<void> save() async {
    if (_currentData == null) {
      print('没有数据可保存 ($storageKey)');
      return;
    }
    try {
      _prefs ??= await SharedPreferences.getInstance();
      final json = _toJson(_currentData as T);
      final jsonString = jsonEncode(json);
      await _prefs!.setString(storageKey, jsonString);
    } catch (e) {
      print('保存数据失败 ($storageKey): $e');
      rethrow;
    }
  }

  /// 更新并保存数据(便捷方法)
  /// [data] 新的数据对象
  Future<void> updateAndSave(T data) async {
    await update(data);
    await save();
  }

  /// 清除本地存储的数据
  /// [clearCurrent] 是否同时清除当前内存中的数据,默认为 true
  Future<void> clear({bool clearCurrent = true}) async {
    try {
      _prefs ??= await SharedPreferences.getInstance();
      await _prefs!.remove(storageKey);
      if (clearCurrent) {
        _currentData = null;
      }
    } catch (e) {
      print('清除数据失败 ($storageKey): $e');
      rethrow;
    }
  }

  /// 将数据转换为 JSON
  /// 尝试动态调用 toJson 方法
  Map<String, dynamic> _toJson(T data) {
    try {
      final result = (data as dynamic).toJson();
      if (result is Map<String, dynamic>) {
        return result;
      }
      throw StateError('类型 $T 的 toJson() 方法必须返回 Map<String, dynamic>');
    } catch (e) {
      if (e is StateError) {
        rethrow;
      }
      throw StateError('类型 $T 必须实现 toJson() 方法以支持序列化: $e');
    }
  }
}

/// 扩展方法:为实现了 toJson 的类型提供便捷的序列化支持
extension JsonSerializableExtension on Object {
  /// 尝试将对象转换为 JSON Map
  Map<String, dynamic>? tryToJson() {
    try {
      final result = (this as dynamic).toJson();
      if (result is Map<String, dynamic>) {
        return result;
      }
      return null;
    } catch (e) {
      return null;
    }
  }
}

// ==================== 使用示例 ====================

/// 示例 1: 普通用户模型
class ExampleUser {
  final String id;
  final String name;
  final String? email;

  ExampleUser({required this.id, required this.name, this.email});

  factory ExampleUser.fromJson(Map<String, dynamic> json) {
    return ExampleUser(
      id: json['id'] as String,
      name: json['name'] as String,
      email: json['email'] as String?,
    );
  }

  Map<String, dynamic> toJson() {
    return {'id': id, 'name': name, if (email != null) 'email': email};
  }

  /// 获取用户管理器单例
  static SingleUserManager<ExampleUser> get manager =>
      SingleUserManager<ExampleUser>(
        storageKey: 'example_user',
        fromJson: (json) => ExampleUser.fromJson(json),
      );
}

/// 示例 2: 商户用户模型
class ExampleMerchant {
  final String merchantId;
  final String merchantName;
  final List<String> permissions;
  final DateTime? lastLoginTime;

  ExampleMerchant({
    required this.merchantId,
    required this.merchantName,
    required this.permissions,
    this.lastLoginTime,
  });

  factory ExampleMerchant.fromJson(Map<String, dynamic> json) {
    return ExampleMerchant(
      merchantId: json['merchantId'] as String,
      merchantName: json['merchantName'] as String,
      permissions: List<String>.from(json['permissions'] as List),
      lastLoginTime: json['lastLoginTime'] != null
          ? DateTime.parse(json['lastLoginTime'] as String)
          : null,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'merchantId': merchantId,
      'merchantName': merchantName,
      'permissions': permissions,
      if (lastLoginTime != null)
        'lastLoginTime': lastLoginTime!.toIso8601String(),
    };
  }

  /// 获取商户管理器单例
  static SingleUserManager<ExampleMerchant> get manager =>
      SingleUserManager<ExampleMerchant>(
        storageKey: 'example_merchant',
        fromJson: (json) => ExampleMerchant.fromJson(json),
      );
}

/// 使用示例代码(在实际项目中可以这样使用):
/// 
/// ```dart
/// // 1. 初始化并加载本地数据
/// final userManager = ExampleUser.manager;
/// final hasLocalData = await userManager.initFromLocal();
/// if (hasLocalData) {
///   final user = userManager.current;
///   print('加载用户: ${user?.name}');
/// }
/// 
/// // 2. 更新用户信息
/// final newUser = ExampleUser(
///   id: '123',
///   name: '张三',
///   email: 'zhangsan@example.com',
/// );
/// await userManager.update(newUser);
/// 
/// // 3. 保存到本地
/// await userManager.save();
/// 
/// // 或者直接更新并保存
/// await userManager.updateAndSave(newUser);
/// 
/// // 4. 获取当前用户
/// final currentUser = userManager.current;
/// if (currentUser != null) {
///   print('当前用户: ${currentUser.name}');
/// }
/// 
/// // 5. 清除数据
/// await userManager.clear();
/// 
/// // 6. 管理多个不同的用户类型
/// final merchantManager = ExampleMerchant.manager;
/// await merchantManager.initFromLocal();
/// 
/// final merchant = ExampleMerchant(
///   merchantId: 'm001',
///   merchantName: '测试商户',
///   permissions: ['read', 'write'],
///   lastLoginTime: DateTime.now(),
/// );
/// await merchantManager.updateAndSave(merchant);
/// ```

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容