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

JSON反序列化最佳实践:OOP下不修改服务端的多接口响应合并方案

最优解决方案

核心思路是遵循依赖注入原则和单一职责原则,解除Picture模型序列化逻辑对全局用户数据的依赖,把用户匹配的逻辑放到上层业务层处理,有两种落地方式可选:


方案1:给fromJson方法传入用户映射参数(轻量场景首选)

直接给Picture的工厂构造方法新增用户ID映射参数,由上层调用方拉取完用户数据后传入,不需要额外新增类:

class Picture {
  final User user;
  final List<String> pictures;

  Picture(this.user, this.pictures);

  // 新增Map<int, User>参数,由外部传入已拉取的用户映射
  factory Picture.fromJson(Map<String, dynamic> json, Map<int, User> userMap) {
    final int userId = json['userID'];
    final User? matchedUser = userMap[userId];
    // 可根据业务需求处理用户找不到的场景:抛异常/过滤/占位
    if (matchedUser == null) {
      throw ArgumentError('未找到ID为$userId的对应用户');
    }
    return Picture(
      matchedUser,
      List<String>.from(json['urls']),
    );
  }
}

调用流程示例:

// 1. 先拉取用户接口,构造ID为key的用户映射(比遍历列表查找效率高)
final userRes = await http.get(Uri.parse('/api/users?page=1'));
final List<User> users = (jsonDecode(userRes.body)['users'] as List)
  .map((item) => User(item['id'], item['name']))
  .toList();
final Map<int, User> userMap = { for (var u in users) u.id: u };

// 2. 拉取图片接口,传入userMap构造Picture实例
final picRes = await http.get(Uri.parse('/api/pictures?page=2'));
final List<Picture> pictures = (jsonDecode(picRes.body)['pictures'] as List)
  .map((item) => Picture.fromJson(item, userMap))
  .toList();

方案2:新增中间DTO层做转换(复杂场景首选)

如果希望保持模型类fromJson方法只接收JSON参数的约定,可新增专门的DTO类承接接口原始返回,再单独做数据合并,分层更清晰:

// 新增PictureDTO,只对应接口原始返回结构
class PictureDto {
  final int userId;
  final List<String> urls;

  PictureDto(this.userId, this.urls);

  factory PictureDto.fromJson(Map<String, dynamic> json) {
    return PictureDto(
      json['userID'],
      List<String>.from(json['urls']),
    );
  }
}

// 单独封装合并逻辑,和模型类完全解耦
List<Picture> mergeUserAndPictureData(List<User> users, List<PictureDto> picDtos) {
  final Map<int, User> userMap = { for (var u in users) u.id: u };
  return picDtos.map((dto) {
    final User user = userMap[dto.userId]!; // 自行处理空值场景
    return Picture(user, dto.urls);
  }).toList();
}

优势说明

  • 完全避免了全局单例的使用,所有依赖都由上层主动传入,符合OOP设计原则
  • 不需要修改服务端返回结构,完全适配现有接口协议
  • 匹配逻辑可灵活调整,适配不同业务场景的异常处理需求

内容的提问来源于stack exchange,提问作者Mahdi Bagheri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:45:02