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

Getter与Setter设计疑问:当前定点浮点转换实现是否合理?

问题分析与优化方案

当前实现的不合理之处

  • Getter存在副作用:Getter里直接修改私有字段_value,违背了Getter的设计初衷——Getter应该是只读操作,不应该改变类的内部状态。外部调用者每次获取Value都可能触发值更新,会导致行为不可预测,比如连续调用Get可能返回不同结果,还会带来不必要的转换开销。
  • 数据一致性风险:依赖ValueUnchanged判断定点值是否变更,但如果外部修改定点值后这个标志没正确更新,Getter会返回旧的浮点值,导致内存中的定点值和类内缓存的浮点值不一致。
  • 职责过于臃肿:Setter里塞了范围检查、反向转换、缓存设置等多个逻辑,违反单一职责原则,后续修改或维护时容易牵一发而动全身。

优化方案:拆分职责+明确同步逻辑

1. 重构Getter,移除副作用

让Getter只负责返回最新值,把定点值到浮点值的同步逻辑抽成独立方法。可以选择两种触发同步的方式:

  • 每次Get时同步(适合定点值频繁变更的场景)
  • 外部主动通知变更时同步(性能更优,推荐)

2. 封装定点值的访问

尽量避免外部直接操作内存中的定点值:

  • 把定点值的读写都封装成Parameter类的内部方法
  • 如果必须允许外部修改,提供明确的NotifyFixedPointValueChanged()方法,让外部修改后主动通知类内部同步,替代Getter被动检查的逻辑

3. 拆分Setter的职责

把范围校验、格式转换、缓存更新等逻辑拆成独立的私有方法,让Setter的逻辑更清晰,也方便单独测试。

优化后的示例代码

private TType _cachedFloatValue;
// 封装定点值存储,避免外部直接访问
private int _fixedPointStorage;

public TType Value
{
    get
    {
        // 若需要每次Get都确保最新,调用同步方法;否则可移除,改用外部通知触发
        SyncFixedPointToFloat();
        return _cachedFloatValue;
    }
    set
    {
        if (value == null || _cachedFloatValue.Equals(value))
            return;

        var validatedValue = ValidateValueRange(value);
        var convertedFixedPoint = ConvertFloatToFixedPoint(validatedValue);

        UpdateFixedPointStorage(convertedFixedPoint);
        _cachedFloatValue = validatedValue;
    }
}

// 同步定点值到浮点值的独立方法
private void SyncFixedPointToFloat()
{
    var currentFixedValue = ReadFixedPointFromStorage();
    var convertedFloat = ConvertFixedPointToFloat(currentFixedValue);
    
    if (!convertedFloat.Equals(_cachedFloatValue))
    {
        _cachedFloatValue = convertedFloat;
    }
}

// 封装定点值读取
private int ReadFixedPointFromStorage()
{
    // 实际读取内存中定点值的逻辑
    return _fixedPointStorage;
}

// 封装定点值更新
private void UpdateFixedPointStorage(int value)
{
    _fixedPointStorage = value;
    CacheFixedPointValue(value);
    // EEPROM同步可放到外部统一处理,或在这里触发
}

// 拆分的独立职责方法
private TType ValidateValueRange(TType value)
{
    // 范围校验逻辑
    return value;
}

private int ConvertFloatToFixedPoint(TType value)
{
    // 浮点转定点的转换逻辑
    return default;
}

private TType ConvertFixedPointToFloat(int fixedValue)
{
    // 定点转浮点的转换逻辑
    return default;
}

private void CacheFixedPointValue(int value)
{
    // 缓存定点值的逻辑
}

// 外部修改定点值后,调用此方法通知同步
public void NotifyFixedPointValueChanged()
{
    SyncFixedPointToFloat();
}

额外建议

  • 优先禁止外部直接修改内存中的定点值,所有操作都通过Parameter类的接口完成,从根源上避免数据不一致问题。
  • 如果必须支持外部直接修改,可考虑用观察者模式:当定点值所在内存区域变更时,主动触发Parameter类的同步逻辑,减少Getter的性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:57:15