如何使用具有相同类名的两种反序列化技术

在我的项目中,我试图同时使用基于Json的反序列化和基于flatBuffer的反序列化。 例如,可以使用ModelInfo包将来自后端api的跟随Json的序列反序列化为名为freezed的类。假设此类在freezed_model.dart

中定义
{
 "model_name":"Model A","model_size": 50
}

现在从同一后端,我想使用平面缓冲区序列化将此信息作为字节数组发送。使用flatc,我可以生成将其反序列化为具有相同名称ModelInfo且具有相同信息的另一个类的代码。假设此类在flatbuffer_model.dart

中可用

我想在Flutter项目中的UI层,管理器或api层中使用这些类,而不会与imports产生冲突。例如,如果我的窗口小部件使用ModelInfo类,则我希望它在freezed_model.dartflatbuffer_model.dart的编译和运行期间被动态解析。也许这是不可能的,但我相信提出要求不会有伤害。

我尝试了有条件的进口和有条件的出口,但飞镖分析仪对此并不满意,我确信我的方法是错误的。

例如我定义了一个名为environment.dart的类,如下所示。

import 'package:scandal_view/src/config_reader.dart';

enum Environment { PROD,DEV }

class CurrentEnvironment {
  static Environment _environment;
  /// assigning a default _decodeMode thinking dart analyser be able to resolve classes during 
  ///conditional export or import.
  static String _decodeMode = 'flatbuffers';

  static void initialize(Environment environment) {
    _environment = environment;
    // reassigns the _decomeMode during runTime.
    _decodeMode = ConfigReader.getDecodemode();
  }

  static Environment get environment => _environment;
  static String get decodeMode => _decodeMode;
}

此后,在我的api类中,我尝试执行以下条件导入,但不起作用。

import 'dummy_model.dart' 
      if(CurrentEnvironment.decodeMode == 'json') 
            'package:mypackage/lib/model/json/freezed_model.dart'
      if(CurrentEnvironment.decodeMode == 'flatbuffer') 
            'package:mypackage/lib/model/flatbuffers/flatbuffer_model.dart'

到目前为止,我的dummy_model.dart为空。之前,我用它来导出上述相同的文件,但没有帮助。我正在考虑为此使用外观模式,但这会导致过多的手写代码,并且在自动生成反序列化器且安全的情况下容易出错。

zzbzzb3732 回答:如何使用具有相同类名的两种反序列化技术

如果我不理解不好,那么您想要实现的目标就是将ModelInfo类与您选择的序列化/反序列化方法(例如json,平面缓冲区等)解耦,对吗?

如果是这种情况,您的有条件进口建议将不起作用(如果确实如此,我认为在维护,测试或扩展它时不是一个好的选择。

我的建议是以最简单的方式遵循某种存储库模式。这将使您真正解耦如何从消费者那里获取数据,这将使您能够选择序列化/反序列化策略,甚至具有多个序列化器等。这种方法也将使在应用程序中添加持久性/缓存超级容易。未来,您是否需要它。

让我们想象一个简单的场景,您想要获取要由业务层(视图模型,块等)然后由UI使用的ModelInfo对象的列表。

首先假设我们有一个ModelInfo类,它是目标类(我们要从服务层发送到App上层的类)。

class ModelInfo {
    // This is the model we want to expose to our upper layers (View Models,Blocs etc) 
}

1)首先,我们将创建一个接口来定义每个ApiDataManager将实现的协定。在Dart中,我们为此使用了抽象类:

abstract class ApiDataManager {
  List<ModelInfo> fetchItems();
}

2-现在,只要符合ApiDataManager,我们就可以创建任意数量的Api数据管理器(json,平面缓冲区等)。在这些管理器上,我们可以导入所需的库并进行相应的api调用,解析等。只要我们有一种返回fetchItems()的{​​{1}}方法,就可以了。

List<ModelInfo>

3-现在,我们创建一个存储库,在其中注入您要使用的远程API数据提供程序(json,flatbuffers)。我们的View Models,Blocs等将使用该存储库来获取数据并获取完整的模型对象。

class jsonApi implements ApiDataManager {

    List<ModelInfo> fetchItems() {
     /* Here you implement a fetchItem method that parses your json server response
     *  and returns an ItemModel list */
    }

}

class flatBuffersApi implements ApiDataManager {
     List<ModelInfo> fetchItems() {
     /* Here you implement a fetchItem method that parses your flatbuffers server response
      *  and returns an ItemModel list */
    }
}

4-最后,我们可以从业务或表示层(我们的Widget)使用我们的存储库,并获取我们的ModelInfo对象列表。实际上,我们可以根据要使用的逻辑在运行时动态注入所需的Api类型。您可以在ViewModel,bloc或Widget中使用类似的逻辑:

class Repository {

  final ApiDataManager remoteDataManager;

  Repository(this.remoteDataManager);


  List<ModelInfo> fetchItems() {

    // Call remoteDataManager.fetchItems()
    // Depending on the remote data manager you have injected you'll be 
    // using json endpoints or flatbuffers,or whatever you want!
    // Return the list to your view models,Blocs etc

    return remoteDataManager.fetchItems();
  }

}

我希望这会有所帮助!

本文链接:https://www.f2er.com/2398177.html

大家都在问