净重和毛重作为单独的值对象

NetWeight and GrossWeight as separate Value Objects

创建不同重量子类型的原因是什么?我看到我们的开发人员创建了 NetWeight 和 GrossWeight 子类型作为值对象。它们都有相同的实现。它有什么价值吗?为什么不对这两种情况都使用权重值类型?我觉得完全不对,想听听专家的意见...如果你觉得不对,你怎么解释为什么不对?

public struct NetWeight : IEquatable<NetWeight>
{
    private const string DefaultMeasurementUnit = "kg";

    public double Value { get; }
    public string MeasurementUnit { get; }

    public NetWeight(double value, string measurementUnit)
    {
        if (value < 0) throw new BusinessRuleValidationException("NetWeight value can't be negative");
        if (string.IsNullOrWhiteSpace(measurementUnit)) throw new BusinessRuleValidationException("NetWeight measurement unit can't be null or whitespace");

        Value = value;
        MeasurementUnit = measurementUnit.Trim();
    }

    public override string ToString()
    {
        return $"{Value}{MeasurementUnit}";
    }
    public static NetWeight operator +(NetWeight left, NetWeight right)
    {
        if (left.MeasurementUnit != right.MeasurementUnit) throw new ArgumentException("Measurement units are not the same");

        return new NetWeight(left.Value + right.Value, left.MeasurementUnit);
    }
    public static NetWeight operator -(NetWeight left, NetWeight right)
    {
        if (left.MeasurementUnit != right.MeasurementUnit) throw new ArgumentException("Measurement units are not the same");

        return new NetWeight(left.Value - right.Value, left.MeasurementUnit);
    }
    public static NetWeight operator *(NetWeight left, Quantity right)
    {
        if (left.MeasurementUnit != right.MeasurementUnit) throw new ArgumentException("Measurement units are not the same");
        return new NetWeight(left.Value * right.Value, left.MeasurementUnit);
    }
    public static NetWeight operator *(Quantity left, NetWeight right)
    {
        if (left.MeasurementUnit != right.MeasurementUnit) throw new ArgumentException("Measurement units are not the same");
        return new NetWeight(left.Value * right.Value, left.MeasurementUnit);
    }

    // TODO: come up with a refactoring that prevents the use of primitive types
    public static NetWeight operator *(NetWeight left, int right)
    {
        return new NetWeight(left.Value * right, left.MeasurementUnit);
    }


    #region IEquatable
    public override bool Equals(object obj)
    {
        return obj is NetWeight weight && Equals(weight);
    }
    public bool Equals(NetWeight other)
    {
        return Value == other.Value &&
               MeasurementUnit == other.MeasurementUnit;
    }
    public override int GetHashCode()
    {
        return HashCode.Combine(Value, MeasurementUnit);
    }
    public static bool operator ==(NetWeight left, NetWeight right)
    {
        return left.Equals(right);
    }
    public static bool operator !=(NetWeight left, NetWeight right)
    {
        return !(left == right);
    }
    #endregion 
}

What would be the reason to create different subtypes of Weight?

如果 GrossWeight 和 NetWeight 在您的领域中是不同的概念,如果用毛重代替净重是错误的,并且如果您使用的语言会标记不兼容的类型,那么建立 GrossWeight 和作为不同类型的 NetWeight 允许您使用该语言自己的类型检查器来标记(从而消除)肯定 类 可能逃逸到生产中的错误。

目前这两种不同类型的权重具有相同的实现,这本质上是一个实现事故。在支持它的语言中,您可以考虑让这两种类型从某个共同的祖先那里继承它们的实现。

许多模型将使用类似的模式处理 标识符 ——即使在实现级别没有差异,区分 CustomerId 类型可能很有用来自 OrderId 类型,以确保您不会因无意中将一个替换为另一个而损坏您的数据集。

您将看到这种方法的另一个地方是在区分不受信任的输入和受信任的数据的模型中。当然,底层原始表示是 "just bytes",但它允许您利用类型系统来区分已通过验证检查点的数据与未通过验证检查点的数据。