创新方案
Flutter 中用 dart:convert 手写模型…
当需要为简单数据结构手写 fromJson/toJson、并把 HTTP 响应解析成模型对象时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
Flutter 中用 dart:conv通用
解决思路
- 引入 dart:convert,用内置的 jsonEncode 做编码、jsonDecode 做解码,手动完成 JSON 序列化。
- 强制类型安全:把 jsonDecode() 返回的 dynamic 结果 cast 成预期类型——对象用 Map<String, dynamic>,数组用 List<dynamic>。
- 封装序列化逻辑:定义普通模型类,属性与 JSON 结构一一对应(用 final),并在类内实现 factory Model.fromJson(Map<String, dynamic> json) 构造器和 Map<String, dynamic> toJson() 方法。
- 在 fromJson 中从 Map 取值并转换为对应的 Dart 类型,可用 switch 模式匹配或显式 cast 提取字段;匹配失败时抛 FormatException(如 throw const FormatException('Failed to load User.'))。
- 在 toJson 中返回一个 Map<String, dynamic>,把类属性映射回 JSON 的字符串键。
- 为 fromJson 和 toJson 都编写单元测试;运行校验器,检查类型不匹配错误并修正 casting 逻辑,确保类型安全、自动补全和编译期异常处理都正常。
- 发请求时用 http 包(如 client.get(Uri.parse(url), headers: {'Accept': 'application/json'}))。
- 校验响应状态码:只有 200(POST 用 201)才继续解析;状态码表示失败时直接 throw Exception,不要返回 null。
- 选择解析策略:小载荷(例如单个对象)在主线程同步解析。
- 大载荷(例如上千个对象的数组、解析耗时 > 16ms)用 compute(parseFunction, response.body) 放到后台 isolate 解析,避免 UI 卡顿;注意传给 compute 的函数必须是顶层函数。
- 解码完成后,把得到的 JSON Map/List 交给模型的 fromJson 构造器完成到模型对象的映射。
- 解析数组时先 (jsonDecode(body) as List<dynamic>).cast<Map<String, dynamic>>(),再 parsed.map<User>((json) => User.fromJson(json)).toList()。
- 大载荷场景把解析逻辑抽成解析函数(如 List<User> parseUsers(String responseBody))供 compute 调用。
- 实现完成后按以下清单逐项核对:定义含 final 属性的普通模型类 → 实现 factory fromJson → 实现 toJson → 为两个方法写单元测试 → 跑校验器、审查类型不匹配错误、修正 casting 逻辑。
适用边界 · 注意事项
- 字段多、嵌套深或结构复杂的 JSON,手写序列化样板代码易错,更适合用 json_serializable 等代码生成方案。
- 解析都很小的单个对象时不要用 compute 丢到后台 isolate,isolate 通信开销反而大于收益。
- 只解码不映射模型、或数据本身无需类型安全(如纯透传 JSON 字符串)时,无需实现整套 fromJson/toJson。