What would be the reason to create different subtypes of Weight? I see our devs created NetWeight and GrossWeight subtypes as Value Objects. They both have the same implementation. Is there any value in it? Why not using Weight value type for both scenarios? I feel its totally wrong, would like to hear an expert's opinion on this...If you feel its wrong, how would you explain why its wrong?
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
}