NetWeight и GrossWeight как отдельные объекты значений - PullRequest
1 голос
/ 19 сентября 2019

Какова будет причина для создания различных подтипов веса?Я вижу, что наши разработчики создали подтипы 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 
}

1 Ответ

2 голосов
/ 19 сентября 2019

В чем причина создания разных подтипов веса?

Если GrossWeight и NetWeight - это разные идеи в вашем домене, если было бы ошибкой заменять вес брутто на вес нетто, и если вы используете язык, который помечает несовместимые типы,затем установление GrossWeight и NetWeight в качестве отдельных типов позволяет вам использовать собственную программу проверки типа языка, чтобы помечать (и тем самым устранять), безусловно, классы ошибок, которые в противном случае могли бы попасть в производство.

Тот факт, что два разных вида весовв настоящее время есть эквивалентные реализации, по сути, случайность реализацииВ тех языках, которые его поддерживают, вы можете рассмотреть возможность того, чтобы эти два типа наследовали свои реализации от какого-то общего предка.

Многие модели будут обрабатывать идентификаторы , используя аналогичный шаблон - даже если на уровне реализациинет никаких отличий, может быть полезно отличить тип CustomerId от типа OrderId, чтобы гарантировать, что вы не повредите свой набор данных, непреднамеренно заменив один на другой.

Другое место, гдевы увидите, что этот подход используется в моделях, которые отличают ненадежные входные данные от надежных данных.Конечно, базовое примитивное представление «просто байты», но оно позволяет вам использовать систему типов, чтобы отличать данные, прошедшие через проверочную контрольную точку, от данных, которые не имеют.

...