You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart如何动态获取YearlyReportArchive类属性并计算年月度总额,求更优方案

优化方案

你当前的实现存在大量重复代码,容易出现笔误(比如现有yearlyTotal方法里把oct放在sep前,虽然不影响求和结果,但后续加顺序相关逻辑很容易出问题),以下是更简洁易维护的实现:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mbpt/utils/tools/validate_double.dart';

// 可选优化:定义月份枚举,替代字符串入参彻底避免传错月份名
enum Month { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }

class YearlyReportArchive {
  // 全局唯一的月份键配置,后续修改仅需调整这里
  static const _monthKeys = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
  // 统一存储所有月份数值
  final Map<String, double> _monthValues;

  // 保留原有属性访问方式,不需要可直接删除
  double get jan => _monthValues['jan']!;
  double get feb => _monthValues['feb']!;
  double get mar => _monthValues['mar']!;
  double get apr => _monthValues['apr']!;
  double get may => _monthValues['may']!;
  double get jun => _monthValues['jun']!;
  double get jul => _monthValues['jul']!;
  double get aug => _monthValues['aug']!;
  double get sep => _monthValues['sep']!;
  double get oct => _monthValues['oct']!;
  double get nov => _monthValues['nov']!;
  double get dec => _monthValues['dec']!;

  YearlyReportArchive._(this._monthValues);

  // 兼容原有字符串参数的月度取值逻辑
  double monthlyTotal(String monthName) {
    return _monthValues[monthName.toLowerCase()] ?? 0.0;
  }

  // 类型更安全的枚举参数月度取值
  double getMonthTotal(Month month) {
    return _monthValues[month.name] ?? 0.0;
  }

  // 自动聚合年度总额,无需手写累加
  double yearlyTotal() {
    return _monthValues.values.fold(0.0, (prev, current) => prev + current);
  }

  factory YearlyReportArchive.fromDoc(DocumentSnapshot doc) {
    final data = doc.data() as Map<String, dynamic>;
    // 批量处理所有月份的数值转换,无需挨个赋值
    final monthValues = Map.fromEntries(
      _monthKeys.map((key) => MapEntry(key, validateDouble(data[key]))),
    );
    return YearlyReportArchive._(monthValues);
  }

  // 保留原有公开构造器,不需要可删除
  factory YearlyReportArchive({
    required double jan,
    required double feb,
    required double mar,
    required double apr,
    required double may,
    required double jun,
    required double jul,
    required double aug,
    required double sep,
    required double oct,
    required double nov,
    required double dec,
  }) {
    final monthValues = {
      'jan': jan,
      'feb': feb,
      'mar': mar,
      'apr': apr,
      'may': may,
      'jun': jun,
      'jul': jul,
      'aug': aug,
      'sep': sep,
      'oct': oct,
      'nov': nov,
      'dec': dec,
    };
    return YearlyReportArchive._(monthValues);
  }
}

优化收益

  • 消除重复代码:所有涉及月份的逻辑无需重复写12次,后续调整仅需修改_monthKeys一处
  • 避免人工失误:无需手写switch、挨个字段赋值、挨个累加,不会出现漏写、写错月份的问题
  • 扩展性更强:后续要加季度统计、按月份索引取值、合法性校验等需求,都可以快速实现
  • 完全向下兼容:原有业务层的调用方式(直接取属性、传字符串取月度值、调用年度总额)都不需要修改

内容的提问来源于stack exchange,提问作者Trax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 02:54:04