**背景:**我想创建一个抽象的JsonSerializable
类,它允许它的扩展器拥有一个toJsonString
-方法和一个fromJsonString
构造函数,这样我就可以将对jsonDecode
和jsonEncode
的所有调用捆绑在一个类中,同时还强制扩展器实现所需的toJson
-metrhod和fromJson
-构造函数。
到目前为止,我已经成功地做到了一半,就像这样:json_serializable.dart
import 'dart:convert';
abstract class JsonSerializable {
Map<String, dynamic> toJson();
String toJsonString() => jsonEncode(toJson());
}
readable_uuid.dart
import 'dart:convert';
import 'package:uuid/uuid.dart';
import 'json_serializable.dart';
class ReadableUuid extends JsonSerializable {
static const Uuid uuidGenerator = Uuid();
String uuid = uuidGenerator.v4();
static const String _uuidFieldName = "uuid";
ReadableUuid();
ReadableUuid.fromJson(Map<String, dynamic> json)
: uuid = json[_uuidFieldName];
ReadableUuid.fromJsonString(String jsonString)
: this.fromJson(jsonDecode(jsonString));
@override
Map<String, dynamic> toJson() => {
_uuidFieldName: uuid,
};
[...]
}
character_id.dart
import 'dart:convert';
import 'package:ceal_chronicler_f/utils/readable_uuid.dart';
import '../utils/json_serializable.dart';
class CharacterId extends JsonSerializable {
static const String _idFieldName = "id";
var id = ReadableUuid();
CharacterId();
CharacterId.fromJson(Map<String, dynamic> json)
: id = ReadableUuid.fromJson(json[_idFieldName]);
CharacterId.fromJsonString(String jsonString)
: this.fromJson(jsonDecode(jsonString));
@override
Map<String, dynamic> toJson() => {
_idFieldName: id,
};
[...]
}
这已经很不错了,但是这里仍然有一些重复。我的两个具体类仍然需要有一个实际上相同的fromJsonString
构造函数,因此它们仍然需要导入dart:convert
。而且,我不能强制它们有这样的fromJson
构造函数。
现在,我想要的是这样的东西:json_serializable.dart
import 'dart:convert';
abstract class JsonSerializable {
abstract JsonSerializable.fromJson(Map<String, dynamic> json);
JsonSerializable.fromJsonString(String jsonString)
: this.fromJson(jsonDecode(jsonString));
Map<String, dynamic> toJson();
String toJsonString() => jsonEncode(toJson());
}
readable_uuid.dart
import 'package:uuid/uuid.dart';
import 'json_serializable.dart';
class ReadableUuid extends JsonSerializable {
static const Uuid uuidGenerator = Uuid();
String uuid = uuidGenerator.v4();
static const String _uuidFieldName = "uuid";
ReadableUuid();
@override
ReadableUuid.fromJson(Map<String, dynamic> json)
: uuid = json[_uuidFieldName];
@override
Map<String, dynamic> toJson() => {
_uuidFieldName: uuid,
};
[...]
}
character_id.dart
import 'package:ceal_chronicler_f/utils/readable_uuid.dart';
import '../utils/json_serializable.dart';
class CharacterId extends JsonSerializable {
static const String _idFieldName = "id";
var id = ReadableUuid();
CharacterId();
@override
CharacterId.fromJson(Map<String, dynamic> json)
: id = ReadableUuid.fromJson(json[_idFieldName]);
@override
Map<String, dynamic> toJson() => {
_idFieldName: id,
};
[...]
}
现在,我知道这是行不通的,因为构造函数不是Dart中接口的一部分(Flutter不允许运行时反射,而支持树抖动,这使得它变得更加复杂)。我的问题是,有谁能想出一个变通方案来尽可能多地实现以下目标:
- 具体类中无重复代码
- 对
dart:convert
的所有依赖都集中在JsonSerializable
中 fromJson
构造函数和toJson
方法被强制存在于具体类中
1条答案
按热度按时间myzjeezk1#
我现在提出了一个“解决方案”,它解决了上述需求中的大约1.75个,但也有一些缺点。
首先,这里是“解决方案”:
json_serializable.dart
readable_uuid.dart
character_id.dart
优点
toJson
和decodeJson
方法缺点
这将是我目前能想到的最好的解决方案。如果有人有更好的解决方案,请随时在这里分享。