首页 > 解决方案 > 如何从 dart 的 Object 类中的子类调用方法作为参数?

问题描述

我在服务类中有一个方法:

@override
  Future<String> registerNewVoter(Object deviceAppInfo) async {
    Dio dio = new Dio();
    final url = API().endpointVoterUri(EndpointVoter.newVoter).toString();
    final header = {'Content-type': 'application/json'};
    final data = await deviceAppInfo; ///need to call the method getInfo() on the Object class which returns a future

    final response =
        await dio.post(url, data: data, options: Options(headers: header));
    if (response.statusCode == 200) {
      Map map = response.data;
      final uuid = map['result']['voter_uuid'];
      return uuid;
    }
    print(
        'Request $url failed\nResponse: ${response.statusCode} ${response.statusMessage}');
    throw response;
  }

我在Object deviceAppInfo方法中使用类型作为参数,以使服务尽可能纯净(遵守 mvvm 原则)。子类DeviceAppInfo有一个名为getInfo()(以及数据来自何处)的异步方法,该方法应该分配给数据(参见代码中的注释)。我正在努力了解如何使该类与 DeviceAppInfo 类分离。有什么建议么...?我正在考虑调用工厂构造函数,但不知道如何实现它。这是我的 DeviceAppInfo 类:

class DeviceAppInfo {
  DeviceAppInfo({
    this.platform,
    this.platformVersion,
    this.appVersion,
  });


  final String platform;
  final String platformVersion;
  final String appVersion;

  Map<String, dynamic> toMap() => {
        'platform': this.platform,
        'platform_version': this.platformVersion,
        'app_version': this.appVersion,
      };

  Future<Map<String, dynamic>> getInfo() async {
    final values = await Future.wait([
      getPlatform(),
      getPlatformVersion(),
      getProjectVersion(),
    ]);

    return DeviceAppInfo(
      platform: values[0],
      platformVersion: values[1],
      appVersion: values[2],
    ).toMap();
  }

  Future<String> getPlatform() async {
    try {
      if (Platform.isIOS) {
        return 'ios';
      }
      return 'android';
    } on PlatformException catch (e) {
      return e.toString();
    }
  }

  Future<String> getPlatformVersion() async {
    try {
      final platformVersion = await GetVersion.platformVersion;
      return platformVersion;
    } on PlatformException catch (e) {
      return e.toString();
    }
  }

  Future<String> getProjectVersion() async {
    try {
      final projectVersion = await GetVersion.projectVersion;
      return projectVersion;
    } on PlatformException catch (e) {
      return e.toString();
    }
  }
}

标签: flutterdart

解决方案


我相信 DeviceAppInfo 是您服务的明确合作者,将其隐藏在 Object 后面简直是糟糕的工程:

  • 它会使您的 Api 难以正确使用且易于错误使用
  • 您的 api 不再是自记录的,如果不阅读文档或代码,就不可能正确使用它。

但是,可以讨论它是否应该作为参数公开或提供给服务的构造函数。

话虽如此,至少有 3 个选项可以将您的服务与 DeviceAppInfo 分离:

选项 1:将 getInfo() 的结果传递给您的方法

  • 解耦入站数据的最不成问题和常见形式
  • 如果您使用 Map 作为输入类型,我有点怀疑,提供不正确键的映射仍然很容易

选项 2:将函数作为参数

  • 函数有点难用,不清楚可以使用代码库中的哪些函数(与类相比)

选项 3:强制转换为动态

请不要那样做

  • 最接近您的问题目标
  • 如果不阅读文档/代码,该功能很难正确使用
  • 您将编译时错误更改为运行时错误

推荐阅读