译:Dart 使用built_value进行序列化

1,078 阅读4分钟
本文介绍了built_value包的其余部分。正如您可能从标题中猜到的那样,主要内容是序列化。

以下是built_value序列化的大体结构:

// 1.使用build_value定义的值类型。
abstract class Login implements Built<Login, LoginBuilder> {
    // Add serialization support by defining this static getter.  
    static Serializer<Login> get serializer => _$loginSerializer;
    ...
}
// 2.每个app一次只会定义一个Serializers将所生成的serializer搜集在一起。
Serializers serializers = _$serializers;
// 3.使用
var login = new Login((b) => b  
    ..username = 'johnsmith'  
    ..password = '123456');
print(JSON.encode(serializers.serialize(login)));
-->["Login", "username", "johnsmith", "password", "123456"]
注意到“ JSON.encode”了吗?序列化程序实际上不像序列化为String那样有效。而是将其转换为Dart的内置JSON序列化知道如何处理的原语。因此,如果您愿意,可以使用JSON以外的其他方式。
您可能将序列化视为应该“起作用”的东西,但是需要进行一些微妙的权衡。让我们深入探讨built_value的序列化。

多态性

built_value的序列化最重要的方面是它支持多态。具体来说,您可以具有抽象类型的字段,并且

  • 该抽象类型的任何可序列化的实现都可以序列化;
  • 足够的信息将被写入网络以反序列化为正确的类型。

最简单的示例是它可以序列化Object列表:

serializers.serialize(new BuiltList <Object>([[1,'two',3]))); 
-> ['list',['int',1,'string''two''int',3]]

仅在反序列化时消除歧义时才需要在导线上添加额外的信息。因此,如果您具有类型为“ BuiltList <int>”的字段,则它将像“ [1、2、3]”那样被序列化,而不会像“ ['int',1,'int',2,'int', 3]”。

最重要的是,您可以根据自己的喜好定义对象模型,并且build_value会序列化它。
如果您想更详细地了解这一点,映射序列化程序测试探讨所有可能性。

多种实现

所有的序列化机制都要面对的另一个问题是定义某种通用序列化的类型。这里的built_json通过允许一个“类型”的多个实现做了一些不寻常的事情这是有效的,因为类型仅通过书写的类名定义例如,没有试图消除名为“Login”的不同类之间的歧义假定发送者和接收者都具有兼容的序列化机制,可用于名为“登录”的类。这增加了有用的灵活性。例如,如果您在服务器和客户端上使用Dart,则可以选择对象模型中的每个类:

  • 您可以在客户端和服务器上使用相同的类。
  • 或者,您可以使用不同的类。实现必须具有相同的名称和兼容的字段。

例如,您可以为客户端提供一个“Login”类,用于处理渲染和解析。以及用于身份验证和数据库的服务器的单独“Login”类。当然,仅服务器实现可自由使用“ dart:io”之类的包,而仅客户机实现如“ dart:html”之类的包。

多种语言

因为build_value序列化仅通过类名标识类型,所以序列化的数据可以很好地映射到任何面向对象的语言。对Java的支持计划通过AutoValue实现

多个版本

序列化的build_value数据以非常简单的方式向后/向前兼容:它依赖于类名和字段名。类名称更改和必填字段名称更改正在中断

可空字段更灵活:在序列化时,仅当非空字段时才写入;反序列化时,如果找不到,则默认为null。因此,可以添加,删除或重命名可为空的字段,这不是一项重大更改。无法识别的字段将被忽略。

没有反射

最后,对于性能至关重要的一点是,built_value不使用任何形状或形式的反射。所有分析都在代码生成时间完成,从而使您获得最少的高性能序列化代码。那就是使用built_value进行序列化。
您可以坐下来编写对象模型,并且可以立即将其序列化以用于RPCS或持久化存储。

枚举类

最后,built_value具有另一个功能:EnumClass。Dart枚举不是类,但是功能强大的对象模型需要表现得像类的枚举。显而易见的模式是创建一个带有“静态常量”字段的类,而EnumClass使其更容易实现。它提供:
  • 为“值”和“ valueOf”生成的代码。
  • 通过build_value序列化器进行序列化。
  • 为Angular或Angular2用户提供了额外的好处:代码生成器可以有选择地生成一个mixin,以帮助您使用模板中的枚举。

所有这些功能都可以在示例看到

原文:medium.com/dartlang/da…