You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Freezed不可变类如何缓存关联Artist对象?求最优方案

解决方法

1. 独立缓存层(最优方案)

既然要避免重复请求API,最合理的方式是把Artist的缓存逻辑从Photo模型中抽离,放到**数据层(比如ArtistRepository)**或专门的缓存类中:

  • 在ArtistRepository里用Map<int, Artist>存储已获取的Artist实例
  • 每次调用getArtist(id)时,先检查缓存:存在则直接返回,不存在再发起API请求,请求成功后写入缓存
  • 这样不管哪个页面或功能需要Artist,调用仓库方法时都会自动复用缓存,完全不需要修改Photo模型

示例代码(修改ArtistRepository):

class ArtistRepository {
  final Map<int, Artist> _artistCache = {};
  final ApiClient _apiClient;

  ArtistRepository(this._apiClient);

  Future<Artist> getArtist({required int id}) async {
    // 优先读取缓存
    if (_artistCache.containsKey(id)) {
      return _artistCache[id]!;
    }
    // 缓存未命中时请求API
    final artist = await _apiClient.fetchArtist(id: id);
    // 写入缓存
    _artistCache[id] = artist;
    return artist;
  }
}

2. 创建组合不可变模型

如果需要在页面间直接传递“Photo+Artist”的组合数据,可以用Freezed封装一个新的不可变类:

@freezed
class PhotoWithArtist with _$PhotoWithArtist {
  factory PhotoWithArtist({
    required Photo photo,
    required Artist artist,
  }) = _PhotoWithArtist;
}

使用时,先通过Photo的artistId获取Artist,再生成这个组合对象,之后在页面和过滤功能中传递该对象即可。

3. 用Freezed Union处理加载状态

如果需要在UI层同步管理“加载中/已加载/加载失败”的状态,可以定义一个Union类型:

@freezed
class PhotoArtistState with _$PhotoArtistState {
  const factory PhotoArtistState.loading(Photo photo) = Loading;
  const factory PhotoArtistState.loaded(Photo photo, Artist artist) = Loaded;
  const factory PhotoArtistState.error(Photo photo, String error) = Error;
}

在状态管理工具(比如Riverpod、Bloc)中处理异步请求,将状态从Loading切换到Loaded,UI层根据状态渲染即可。


替代库推荐

如果觉得Freezed的不可变约束过于受限,可以考虑:

  • built_value:同属不可变模型库,支持更灵活的自定义逻辑(比如延迟加载的计算属性),但需要额外配置代码生成规则
  • json_serializable + 手动不可变类:放弃自动生成,手动编写带copyWith方法的不可变类,完全控制字段和逻辑,适合高度自定义的场景

内容的提问来源于stack exchange,提问作者Stelios Papamichail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:27:30