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

Dart中同类型对象间属性依赖的实现方案咨询

Dart中实现依赖对象属性自动更新的可靠方案

你需要实现的核心场景:

  • 多个Item类对象共存
  • 某个Item(如objectB)的price属性依赖另一个Item(如objectA)的price,且按固定比例计算得出
  • 希望objectB的price存储实际计算值,而非仅保留计算规则

以下是两种可靠的实现方案:

方案1:Getter封装计算逻辑(简易版)

如果不需要实时持久化计算值,只是希望调用者透明获取最新值,可以用Getter替代直接暴露price属性,内部根据isCalculated判断返回自身存储值或基于依赖对象计算的结果。同时需要一个全局容器管理所有Item,方便通过ID查找依赖对象:

final Map<String, Item> itemRegistry = {};

class Item {
  final String id;
  double _price = 0;
  final bool isCalculated;
  final String dependsOn;
  final double percentage;

  // 对外暴露的price getter,自动处理计算逻辑
  double get price {
    if (!isCalculated) return _price;
    final dependency = itemRegistry[dependsOn];
    if (dependency == null) return _price;
    // 如需存储计算值,可在此处同步更新_price
    return dependency.price * percentage;
  }

  // 手动触发计算并存储值的方法
  void updateCalculatedPrice() {
    if (!isCalculated) return;
    final dependency = itemRegistry[dependsOn];
    if (dependency != null) {
      _price = dependency.price * percentage;
    }
  }

  Item({
    required this.id,
    double price = 0,
    this.dependsOn = '',
    this.isCalculated = false,
    this.percentage = 1,
  }) : _price = price {
    itemRegistry[id] = this;
  }
}

void main() {
  Item item1 = Item(id: 'aaa', price: 10);
  Item item2 = Item(
    id: 'bbb',
    isCalculated: true,
    dependsOn: 'aaa',
    percentage: 0.1,
  );

  print(item2.price); // 输出1.0
  item1._price = 20;
  print(item2.price); // 输出2.0(即时获取最新计算值)
  
  item2.updateCalculatedPrice();
  print(item2._price); // 输出2.0(存储计算后的值)
}

优势:实现简单,调用者无需区分对象类型,直接访问price即可;不足:依赖对象频繁变化时会重复计算,存储计算值需手动触发更新。

方案2:观察者模式(自动更新存储值)

如果希望依赖对象的price变化时,自动更新当前对象的存储price,可以用观察者模式实现,让依赖对象维护观察者列表,属性变更时主动通知更新:

final Map<String, Item> itemRegistry = {};

class Item {
  final String id;
  double _price = 0;
  final bool isCalculated;
  final String dependsOn;
  final double percentage;
  // 维护依赖当前对象的观察者列表
  final List<Item> _observers = [];

  double get price => _price;
  set price(double newValue) {
    _price = newValue;
    // 价格变更时通知所有观察者更新
    _notifyObservers();
  }

  Item({
    required this.id,
    double price = 0,
    this.dependsOn = '',
    this.isCalculated = false,
    this.percentage = 1,
  }) : _price = price {
    // 计算型对象自动注册为依赖对象的观察者
    if (isCalculated) {
      final dependency = itemRegistry[dependsOn];
      dependency?._addObserver(this);
      // 初始化计算值
      updateCalculatedPrice();
    }
    itemRegistry[id] = this;
  }

  void _addObserver(Item observer) {
    _observers.add(observer);
  }

  void _notifyObservers() {
    for (final observer in _observers) {
      observer.updateCalculatedPrice();
    }
  }

  void updateCalculatedPrice() {
    if (!isCalculated) return;
    final dependency = itemRegistry[dependsOn];
    if (dependency != null) {
      _price = dependency.price * percentage;
    }
  }
}

void main() {
  Item item1 = Item(id: 'aaa', price: 10);
  Item item2 = Item(
    id: 'bbb',
    isCalculated: true,
    dependsOn: 'aaa',
    percentage: 0.1,
  );

  print(item2.price); // 输出1.0
  item1.price = 20;
  print(item2.price); // 自动更新为2.0
}

核心逻辑:

  • 每个Item维护观察者列表,自身price变化时通知所有依赖它的对象
  • 计算型Item创建时自动注册到依赖对象的观察者列表,完成初始化计算
  • 计算值始终存储在_price中,依赖对象变更时自动同步更新

方案选择建议

  • 追求简单实现、对性能要求不高:选方案1
  • 需要依赖对象变更时自动同步存储值、要求数据一致性:选方案2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 19:13:29