Настраиваемые свойства отображения для моделей предметной области

Используя DDD и следуя шаблону чистой архитектуры, я немного запутался в том, где идеальное место для настройки свойств отображения для конкретных идентификаторов модели домена. Это звучит запутанно, я думаю, что лучше всего могу объяснить это на примере:

Здесь бизнес-логика модели предметной области проста: вычисление «масштабированного» значения на основе ввода, усиления и смещения.

//Domain Model
public class Transducer
{
    //Name is the ID
    public string Name { get; set; }
    public double Gain { get; set; }
    public double Offset { get; set; }
    public double RawValue { get; set; }

    public double ScaledValue { get; private set; }


    public double CalculateScaledValue(double RawValue)
    {
        ScaledValue = (Gain * RawValue) + Offset;
        return ScaledValue;
    }

}

У нас есть вариант использования, который координирует действия пользователя с моделями предметной области и управляет постоянством. Детали здесь не важны, поэтому я включил только пример интерфейса:

//implementation of execution of business logic and persistance would go in the implentation, details left out for this example
public interface ITransducerUseCase
{
    IEnumerable<string> GetAllTransducerNames();
    void AddNewTransducer(string Name, double Gain, double Offset);
    void SetGain(string Name, double Gain);
    void SetOffset(string Name, double Offset);
    void SetRawValue(string Name, double Raw);

    double GetScaledValue(string Name);

}

Вариант использования используется контроллером для координации вариантов использования с представлением или другим контроллером. Этот специальный контроллер позволяет просматривать имена всех преобразователей и может изменять их свойство усиления.

public class Controller
{
    ITransducerUseCase _TransducerUseCase;

    //these are sent to the view to be displayed
    public Dictionary<string, double> _transducerScaledValues = new Dictionary<string, double>();

    public Controller(ITransducerUseCase TransducerUseCase)
    {
        _TransducerUseCase = TransducerUseCase;
        //Get all the names and populate the dictionary to display.
        foreach (var transducerName in _TransducerUseCase.GetAllTransducerNames())
            _transducerScaledValues.Add(transducerName, _TransducerUseCase.GetScaledValue(transducerName));
    }

    //bound to the view
    public string SelectedName { get; set; }
    //bound to the view, a property for setting a new gain value
    public double Gain { get; set; }

    public void OnButtonClick()
    {
        //update the gain
        _TransducerUseCase.ChangeGain(SelectedName, Gain);
        //get the new scaled value            
        _transducerScaledValues[SelectedName] = _TransducerUseCase.GetScaledValue("PumpPressure");

    }
}

Это леса для этого вопроса. Вот новое требование:

  • Мы хотим иметь параметр конфигурации уровня приложения для «количества знаков после запятой», которое отображается для ScaledValue из Transducer на основе идентификации. Таким образом, датчик с идентификатором «PumpPressure» может иметь значение DisplayRounding, отличное от датчика с именем «PumpTemperature».

  • Этот параметр должен распространяться на все приложение (используйте этот параметр всякий раз, когда отображается значение). Этот параметр также можно использовать, если ScaledValue когда-либо регистрировалось в файле, так что это сквозная бизнес-потребность.

Решения, о которых я подумал: Размещение свойства в модели предметной области и возвращение его через слои в представление. Это не кажется логичным, потому что свойство DisplayRounding не имеет никакого отношения к бизнес-логике.

public class Transducer
{
    //This seems like an SRP violation
    public int DisplayRounding { get; set; }

    //Name is the ID
    public string Name { get; set; }
    public double Gain { get; set; }
    public double Offset { get; set; }

    public double ScaledValue { get; private set; }


    public double CalculateScaledValue(double RawValue)
    {
        ScaledValue = (Gain * RawValue) + Offset;
        return ScaledValue;
    }

}

Если не там, то где?

Можем ли мы поместить его в отдельную модель предметной области без какой-либо бизнес-логики? Постоянство может управляться тем же классом варианта использования или отдельным классом.

public class TransducerDisplaySettings
{
    public int Rounding { get; set; }
    //plus other related properties
} 

Плюсы: это лучше разделяет проблемы, чем одна комбинированная модель.

Минусы: В модели нет никакой бизнес-логики, это нормально?


Мы также рассмотрели возможность полного управления этими настройками на внешних слоях с помощью какой-либо службы.

Плюсы: нет моделей предметной области без бизнес-логики.

Минусы: Вероятно, будет привязан к определенному фреймворку?


Есть ли еще плюсы/минусы, которые я упускаю? Является ли один подход явно лучше другого? Есть ли подход, который я полностью пропустил? Спасибо!


person Dru Steeby    schedule 08.11.2018    source источник


Ответы (2)


Основное решение, которое вам нужно будет принять, заключается в том, является ли округление отображения аспектом бизнес-логики вашего приложения или «просто аспектом отображения».

Если вы считаете, что это важно для вашей бизнес-логики, это должно быть смоделировано с вашими сущностями.

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

person plainionist    schedule 10.02.2019
comment
Первый случай мне понятен. В дополнение к примеру я мог предвидеть необходимость отображения как округленного, так и неокругленного значения. В этом случае я думаю, что было бы разумно, чтобы бизнес-логика содержала оба значения, и чтобы уровень приложения/отображения выбирал, какое из них использовать, вы согласны? Если вы рассматриваете это просто как аспект представления значений пользователю, его следует хранить в отдельном репозитории или службе, а затем применять презентатор. Было бы это так, если бы значение округления не не имеет значения с точки зрения потребностей бизнеса? - person Dru Steeby; 14.02.2019
comment
Да. Другими словами: если округление необходимо просто для того, чтобы значения выглядели красиво и были хорошо отформатированы в пользовательском интерфейсе, тогда оставьте конфигурацию округления отдельно и позвольте презентатору/модели представления применить ее. - person plainionist; 14.02.2019

person    schedule
comment
Вопрос касается свойства DisplayRounding, а не Name - person Dru Steeby; 08.11.2018